Documentation
¶
Overview ¶
Package httpapi is ContentKit's HTTP surface as data. Every route of every module is declared once, as a Route in the module's table: method, path, auth tier, query, bodies and error codes. The module mounts its handlers from that table (Mount), and internal/contract renders the same tables as api/openapi.json, the browser SDK's generated types and docs/api/routes.md.
Index ¶
- Constants
- Variables
- func ErrorSet(name string) []string
- func H[S any](fn func(S, http.ResponseWriter, *http.Request)) func(S) http.HandlerFunc
- func Mount[S any](mux *http.ServeMux, guard Guard, s S, routes []Route[S])
- func Register[S any](m Module, routes []Route[S])
- func Reserved() []string
- type ErrorCode
- type Guard
- type Module
- type Param
- type Reply
- type Route
- type Spec
- type Stream
- type Tier
Constants ¶
const ( CodeInvalidRequest = "invalid_request" CodeForbidden = "forbidden" CodeNotFound = "not_found" CodeConflict = "conflict" CodeRateLimited = "rate_limited" CodeUpgrade = "upgrade_required" CodeInternal = "internal_error" CodeTenantMismatch = "tenant_mismatch" )
The codes more than one module answers.
const (
GET, POST, PUT, PATCH, DELETE = http.MethodGet, http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete
)
Variables ¶
Modules lists every module in catalog order.
var NoContent = Reply{Status: http.StatusNoContent}
NoContent is a 204.
var Page = []Param{Int("limit", "page size: 20 by default, at most 100"), Int("offset", "items to skip")}
Page is the limit/offset query of a list.
Functions ¶
func H ¶
func H[S any](fn func(S, http.ResponseWriter, *http.Request)) func(S) http.HandlerFunc
H adapts a handler method expression, such as (*posts).handleList, to Serve.
func Mount ¶
Mount registers routes on mux, served from s, each behind guard. Without a guard only Open routes mount: a route is never mounted ungated.
Types ¶
type ErrorCode ¶
ErrorCode is one stable error code: every module answers the flat body {"error", "code", …}, where code is one of these with its status. Clients branch on the code; the message is for people and may change.
func LookupErrorCode ¶
LookupErrorCode returns a registered code.
type Module ¶
type Module string
Module is one mountable handler. contentkit.Runtime.Handler serves every configured module under one prefix, each at its fixed sub-path (Prefix).
const ( // Content is posts, comments, reactions, favorites, polls, comment bans // and moderation (content.Runtime.Handler). Content Module = "content" // Upload is the media upload API (media.UploadHandler). Upload Module = "upload" // Media is the media read API and playlists (media.Reader.Handler). Media Module = "media" // Codes resolves content codes (contenturl.Router.Handler). Codes Module = "codes" // Taxonomy is the taxonomy admin API (taxonomy.Handler). Taxonomy Module = "taxonomy" )
type Param ¶
type Param struct {
Name string
// Kind is string, integer, number, boolean, flag (present means on),
// strings (repeated) or list (comma-separated).
Kind string
Doc string
}
Param is one query parameter.
type Reply ¶
Reply is one success outcome: its status and a zero value of its body's type (nil for none).
type Route ¶
type Route[S any] struct { Spec Serve func(S) http.HandlerFunc }
Route is a Spec with the handler that serves it, built from the state S the module mounts with.
type Spec ¶
type Spec struct {
Method string
// Path is the route from its module's mount, in ServeMux syntax.
Path string
// Resource is the route's section in the docs and its OpenAPI tag.
Resource string
// Doc says what the route does, in one line.
Doc string
Auth Tier
// Perm is the permission a Staff route checks, an access.Permission's
// full name: root:<resource>:<action>.
Perm string
// Query lists the query parameters; Request is a zero value of the JSON
// body's type (nil for none); Responses is every success outcome.
Query []Param
Request any
Responses []Reply
// Errors lists the route's own codes; ErrorSets names the shared ones.
Errors []string
// Module is set by Register.
Module Module
}
Spec is a route without its handler: what the contract is generated from.
func Catalog ¶
func Catalog() []Spec
Catalog is every registered route, by module (Modules order), each module in declaration order.
func Match ¶
Match finds the catalog route serving a method and a path under the one mount, preferring literal segments as ServeMux does.
func (Spec) ErrorSets ¶
ErrorSets names the shared code sets a route answers besides its own Errors.
type Stream ¶
type Stream struct{ ContentType string }
Stream is a body that is not JSON: an image, a playlist.
type Tier ¶
type Tier string
Tier is what a route requires of its caller before its handler acts. The module's gate enforces it from the host's auth.Authenticator, asked at most once per request.
const ( // Open: anyone; the route reads no actor and never authenticates. Open Tier = "open" // Public: the actor is optional: anonymous without a credential, else the // one the credential proves (401 unauthorized for one that fails); the // host's resolver decides what it sees. Public Tier = "public" // User: a signed-in person; 401 unauthorized without a credential, 403 // forbidden for an application. User Tier = "user" // Staff: a person or an application holding Perm in the root scope of // the host's auth; 401 unauthorized without a credential, 403 forbidden // without the permission. Staff Tier = "staff" )