Documentation
¶
Overview ¶
Package resources provides v2 resource registration with seven standard CRUD operations, inspired by Buffalo's resource pattern.
A Resource defines the seven operations:
- List: GET /{resource}
- Show: GET /{resource}/{id}
- New: GET /{resource}/new
- Create: POST /{resource}
- Edit: GET /{resource}/{id}/edit
- Update: PUT /{resource}/{id}
- Destroy: DELETE /{resource}/{id}
PATCH is an optional alias of Update, not a separate seventh operation.
Each operation is independently typed with its own request and response types via handlers.Endpoint[Req, Resp], providing compile-time type safety. Operations that are not supported return nil and are registered with a default 405 response via ResourceDefaults.
Two resource interfaces are provided:
- Resource[ID]: the recommended interface for v2 migration. Each operation returns handlers.EndpointRuntime. Implement this for simple CRUD + custom (non-CRUD) resources. Pair with ResourceBuilder for fluent registration.
- TypedResource[ID, ...]: advanced interface with per-operation type parameters (14 type params). Each operation returns a fully typed *handlers.Endpoint[Req, Resp]. This is overkill for most resources — use it only when you need the strictest compile-time guarantees on every operation's request/response types. Any TypedResource automatically satisfies Resource[ID].
For v2 migration, the recommended path is:
resources.NewResource[string]("/users"). // ResourceBuilder
EnablePatch().
WithCustom(reloadOp).
Register(router, core, respHandler, &UserResource{}) // implements Resource[ID]
Avoid TypedResource unless you have a specific need for 14-type-parameter strictness — the verbosity outweighs the benefit for simple CRUD resources.
Index ¶
- func GetParsedID[ID cmp.Ordered](ctx *v2wf.RequestContext, idParam string) (ID, error)
- func Register[ID cmp.Ordered](router routing.RouteGroup, config Config[ID]) error
- type Config
- type CustomOperation
- type Resource
- type ResourceBuilder
- func (b *ResourceBuilder[ID]) EnablePatch() *ResourceBuilder[ID]
- func (b *ResourceBuilder[ID]) Register(router routing.RouteGroup, core requestCore.RequestCoreInterface, ...) error
- func (b *ResourceBuilder[ID]) WithCustom(ops ...CustomOperation) *ResourceBuilder[ID]
- func (b *ResourceBuilder[ID]) WithDefaults(d *ResourceDefaults) *ResourceBuilder[ID]
- func (b *ResourceBuilder[ID]) WithIDParam(name string) *ResourceBuilder[ID]
- func (b *ResourceBuilder[ID]) WithIDParser(fn func(string) (ID, error)) *ResourceBuilder[ID]
- type ResourceDefaults
- type TypedResource
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetParsedID ¶
GetParsedID retrieves a parsed ID from the request context's locals. This is used by resource handlers to access the ID parsed by withIDParser. The RequestContext is available on the HandlerRequest's V2 field.
Types ¶
type Config ¶
type Config[ID cmp.Ordered] struct { // Path is the base path for the resource (e.g. "/users"). Path string // Resource implements the seven operations. Resource Resource[ID] // Core is the v1 RequestCoreInterface for infrastructure access. // May be nil for pure v2 applications. Core requestCore.RequestCoreInterface // RespHandler is the v2 response handler. RespHandler *v2response.Handler // IDParam is the URL parameter name for the resource ID. // Default: "id". IDParam string // IDParser converts a string URL parameter to the ID type. // If nil, the string value is used directly for string IDs. IDParser func(string) (ID, error) // EnablePatchAlias, when true, registers PATCH as an alias for // Update on the /{id} path. EnablePatchAlias bool // Defaults provides 405 handlers for unsupported operations. // If nil, unsupported operations are silently skipped. Defaults *ResourceDefaults // Custom registers non-CRUD operations (e.g. Reload, Validate) // alongside the standard 7 operations. Custom operations are // registered before /{id} routes for correct path precedence. Custom []CustomOperation }
Config holds the configuration for registering a resource.
type CustomOperation ¶
type CustomOperation struct {
// Method is the HTTP method (GET, POST, PUT, DELETE, PATCH).
Method string
// Path is the sub-path appended to the resource base path.
// Must start with "/". For example: "/reload", "/validate".
Path string
// Endpoint is the typed endpoint descriptor for the operation.
Endpoint handlers.EndpointRuntime
}
CustomOperation defines a non-CRUD action registered alongside a resource. Common use cases include Reload, Validate, Approve, or other domain-specific actions that don't fit the 7 standard operations.
The Path is appended to the resource's base Path. For example, if the resource Path is "/parameters" and the CustomOperation Path is "/reload", the full route is "POST /parameters/reload".
Custom operations are registered before /{id} routes to ensure correct precedence (e.g. "/parameters/reload" won't match "/{id}").
type Resource ¶
type Resource[ID cmp.Ordered] interface { // List returns a list of resources. List() handlers.EndpointRuntime // Show returns a single resource by ID. Show() handlers.EndpointRuntime // New returns the form/data for creating a new resource. New() handlers.EndpointRuntime // Create creates a new resource. Create() handlers.EndpointRuntime // Edit returns the form/data for editing a resource by ID. Edit() handlers.EndpointRuntime // Update replaces a resource by ID. Update() handlers.EndpointRuntime // Destroy deletes a resource by ID. Destroy() handlers.EndpointRuntime }
Resource defines the seven standard CRUD operations for a resource. Each operation returns an EndpointRuntime — a type-erased interface that can be registered on a router. Operations returning nil are not supported and will be registered with a default 405 handler.
ID must be cmp.Ordered (string, int, int64, float64, etc.) to ensure IDs can be compared and sorted at compile time.
type ResourceBuilder ¶
ResourceBuilder provides a fluent API for constructing and registering resources. It is the recommended way to register resources in v2 application code — prefer it over passing raw Config[ID] to Register.
The typical v2 migration path is:
resources.NewResource[string]("/users").
EnablePatch().
WithCustom(reloadOp).
Register(router, core, respHandler, &UserResource{})
where UserResource implements Resource[string] (not TypedResource).
func NewResource ¶
func NewResource[ID cmp.Ordered](path string) *ResourceBuilder[ID]
NewResource creates a ResourceBuilder for the given base path. The ID type parameter must be cmp.Ordered (string, int, int64, etc.).
func (*ResourceBuilder[ID]) EnablePatch ¶
func (b *ResourceBuilder[ID]) EnablePatch() *ResourceBuilder[ID]
EnablePatch enables PATCH as an alias for Update on the /{id} path.
func (*ResourceBuilder[ID]) Register ¶
func (b *ResourceBuilder[ID]) Register( router routing.RouteGroup, core requestCore.RequestCoreInterface, respHandler *v2response.Handler, resource Resource[ID], ) error
Register registers all resource operations on the given router using the builder's configuration.
func (*ResourceBuilder[ID]) WithCustom ¶
func (b *ResourceBuilder[ID]) WithCustom(ops ...CustomOperation) *ResourceBuilder[ID]
WithCustom adds custom (non-CRUD) operations to the resource.
func (*ResourceBuilder[ID]) WithDefaults ¶
func (b *ResourceBuilder[ID]) WithDefaults(d *ResourceDefaults) *ResourceBuilder[ID]
WithDefaults sets the ResourceDefaults for 405 handlers on unsupported operations.
func (*ResourceBuilder[ID]) WithIDParam ¶
func (b *ResourceBuilder[ID]) WithIDParam(name string) *ResourceBuilder[ID]
WithIDParam sets the URL parameter name for the resource ID. Default: "id".
func (*ResourceBuilder[ID]) WithIDParser ¶
func (b *ResourceBuilder[ID]) WithIDParser(fn func(string) (ID, error)) *ResourceBuilder[ID]
WithIDParser sets a custom ID parser function.
type ResourceDefaults ¶
type ResourceDefaults struct{}
ResourceDefaults holds default endpoint handlers for unsupported operations. When a Resource returns nil for an operation, the corresponding default handler emits a 405 Method Not Allowed response.
type TypedResource ¶
type TypedResource[ ID cmp.Ordered, ListReq, ListResp any, ShowReq, ShowResp any, NewReq, NewResp any, CreateReq, CreateResp any, EditReq, EditResp any, UpdateReq, UpdateResp any, DestroyReq, DestroyResp any, ] interface { List() *handlers.Endpoint[ListReq, ListResp] Show() *handlers.Endpoint[ShowReq, ShowResp] New() *handlers.Endpoint[NewReq, NewResp] Create() *handlers.Endpoint[CreateReq, CreateResp] Edit() *handlers.Endpoint[EditReq, EditResp] Update() *handlers.Endpoint[UpdateReq, UpdateResp] Destroy() *handlers.Endpoint[DestroyReq, DestroyResp] }
TypedResource is an advanced resource interface with per-operation type parameters. Implementing this interface gives compile-time type safety for all 7 operations — each operation returns a fully typed *handlers.Endpoint[Req, Resp].
Any TypedResource automatically satisfies Resource[ID] because *handlers.Endpoint[Req, Resp] implements handlers.EndpointRuntime.
The 14 type parameters (7 request + 7 response types) make this verbose to spell out. For most v2 migration use cases (simple CRUD + custom operations like Reload), prefer Resource[ID] with ResourceBuilder — the 14 type parameters are overkill. Use TypedResource only when you need the strictest compile-time guarantees on every operation's request/response types simultaneously.