Documentation
¶
Overview ¶
Package pagination adapts typed database pages to HTTP request and response contracts. Applications supply domain filters, page reads and explicit DTOs; the framework owns parsing, limits, metadata and navigation links.
Index ¶
- Constants
- func Authenticated[P, F, W, A, Page, Response any](endpoint pageEndpoint[P, F, W, Page, Response], ...) authenticatedPageEndpoint[P, F, W, A, Page, Response]
- func AuthenticatedEndpointID[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response]) foundryhttp.RouteID
- func AuthenticatedEndpointMethod[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response]) foundryhttp.Method
- func AuthenticatedEndpointPattern[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response]) string
- func AuthenticatedURL[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response], ctx context.Context, ...) (string, error)
- func AuthorizeActor[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response], ...) authenticatedPageEndpoint[P, F, W, A, Page, Response]
- func Configure[P, F, W, Page, Response any](endpoint pageEndpoint[P, F, W, Page, Response], ...) pageEndpoint[P, F, W, Page, Response]
- func ConfigureAuthenticated[P, F, W, A, Page, Response any](endpoint authenticatedPageEndpoint[P, F, W, A, Page, Response], ...) authenticatedPageEndpoint[P, F, W, A, Page, Response]
- func CursorJSON[T any](item contract.JSON[T]) contract.JSON[CursorResponse[T]]
- func CursorQuery[M any]() foundryhttp.QueryCodec[orm.Cursor[M]]
- func EndpointID[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response]) foundryhttp.RouteID
- func EndpointMethod[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response]) foundryhttp.Method
- func EndpointPattern[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response]) string
- func Handle[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response], ...) foundryhttp.RouteRegistration
- func HandleAuthenticated[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response], ...) foundryhttp.RouteRegistration
- func Inspect[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response]) (foundryhttp.EndpointInfo, error)
- func InspectAuthenticated[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response]) (foundryhttp.EndpointInfo, error)
- func MapPage[From, To any](ctx context.Context, page orm.PageResult[From], mapper func(From) (To, error)) (orm.PageResult[To], error)
- func MapSimplePage[From, To any](ctx context.Context, page orm.SimplePage[From], mapper func(From) (To, error)) (orm.SimplePage[To], error)
- func MessageDefinitions() []i18n.MessageDefinition
- func NumberedJSON[T any](item contract.JSON[T]) contract.JSON[NumberedResponse[T]]
- func SimpleJSON[T any](item contract.JSON[T]) contract.JSON[SimpleResponse[T]]
- func URL[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response], ctx context.Context, path P, ...) (string, error)
- func Validate[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response]) error
- func ValidateAuthenticated[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response]) error
- func ValidateFilters[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response], rules ...validation.Rule[F]) pageEndpoint[P, F, W, Page, Response]
- func ValidatePath[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response], rules ...validation.Rule[P]) pageEndpoint[P, F, W, Page, Response]
- type AuthenticatedCursorEndpoint
- type AuthenticatedNumberedEndpoint
- type AuthenticatedSimpleEndpoint
- type Config
- type CursorConfig
- type CursorEndpoint
- type CursorMeta
- type CursorRequest
- type CursorResponse
- type CursorResult
- type LinkMode
- type Links
- type NumberedEndpoint
- type NumberedMeta
- type NumberedResponse
- type PageLink
- type Parameters
- type Request
- type SimpleEndpoint
- type SimpleMeta
- type SimpleResponse
Constants ¶
const ( NumberLabelKey i18n.MessageKey = "http.pagination.page" SizeLabelKey i18n.MessageKey = "http.pagination.size" )
Label keys of the page number and page size parameters. Validation issues and exported parameter metadata carry them; their English labels are built in, and an application translates them, English included, in its catalog.
const DefaultMaximumPage = 10_000
DefaultMaximumPage bounds offset scans at MaximumPage*MaximumSize rows.
const MaximumPageWindow = 10
MaximumPageWindow bounds the per-response link generation of a page window.
Variables ¶
This section is empty.
Functions ¶
func Authenticated ¶
func Authenticated[P, F, W, A, Page, Response any](endpoint pageEndpoint[P, F, W, Page, Response], binding foundryhttp.GuardBinding[A], options ...foundryhttp.GuardOption[A]) authenticatedPageEndpoint[P, F, W, A, Page, Response]
Authenticated binds a Guarded numbered, simple or cursor endpoint to its concrete actor. Configure scope, middleware, limits, errors and validation on the page before binding. Authentication and authority retain the ordinary HTTP lifecycle.
func AuthenticatedEndpointID ¶ added in v0.2.0
func AuthenticatedEndpointID[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response]) foundryhttp.RouteID
func AuthenticatedEndpointMethod ¶ added in v0.2.0
func AuthenticatedEndpointMethod[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response]) foundryhttp.Method
func AuthenticatedEndpointPattern ¶ added in v0.2.0
func AuthenticatedURL ¶ added in v0.3.0
func AuthenticatedURL[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response], ctx context.Context, path P, filters F, page W) (string, error)
AuthenticatedURL validates the guarded endpoint and builds a URL from concrete route, filter and pagination values using the public adapter's link policy.
func AuthorizeActor ¶ added in v0.2.0
func AuthorizeActor[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response], authorize func(context.Context, A, pageRequest[P, F, W]) error) authenticatedPageEndpoint[P, F, W, A, Page, Response]
AuthorizeActor receives the actor and validated page request before the read. It uses HTTP request-hook isolation and error mapping, including nil validation.
func Configure ¶ added in v0.2.0
func Configure[P, F, W, Page, Response any](endpoint pageEndpoint[P, F, W, Page, Response], options ...foundryhttp.EndpointOption) pageEndpoint[P, F, W, Page, Response]
func ConfigureAuthenticated ¶ added in v0.2.0
func ConfigureAuthenticated[P, F, W, A, Page, Response any](endpoint authenticatedPageEndpoint[P, F, W, A, Page, Response], options ...foundryhttp.GuardOption[A]) authenticatedPageEndpoint[P, F, W, A, Page, Response]
func CursorJSON ¶
CursorJSON composes an explicit item DTO with count-free cursor metadata.
func CursorQuery ¶
func CursorQuery[M any]() foundryhttp.QueryCodec[orm.Cursor[M]]
CursorQuery supplies the same typed, bounded cursor codec to custom query declarations. Its scalar metadata preserves the original model/result owner. Successful parsing validates structure; query execution verifies scope.
func EndpointID ¶ added in v0.2.0
func EndpointID[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response]) foundryhttp.RouteID
func EndpointMethod ¶ added in v0.2.0
func EndpointMethod[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response]) foundryhttp.Method
func EndpointPattern ¶ added in v0.2.0
func Handle ¶ added in v0.3.0
func Handle[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response], handler func(context.Context, pageRequest[P, F, W]) (Page, error)) foundryhttp.RouteRegistration
Handle binds a domain page read. Input validation completes first; response metadata and links are completed before native JSON commits any success bytes.
func HandleAuthenticated ¶ added in v0.3.0
func HandleAuthenticated[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response], handler func(context.Context, A, pageRequest[P, F, W]) (Page, error)) foundryhttp.RouteRegistration
HandleAuthenticated preserves actor, request and ORM page types through the ordinary guarded HTTP handler. Page validation, navigation and response completion are shared with the public adapter; authority is never inferred from a cursor token.
func Inspect ¶ added in v0.2.0
func Inspect[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response]) (foundryhttp.EndpointInfo, error)
func InspectAuthenticated ¶ added in v0.2.0
func InspectAuthenticated[P, F, W, A, Page, Response any](e authenticatedPageEndpoint[P, F, W, A, Page, Response]) (foundryhttp.EndpointInfo, error)
func MapPage ¶
func MapPage[From, To any](ctx context.Context, page orm.PageResult[From], mapper func(From) (To, error)) (orm.PageResult[To], error)
MapPage converts complete source rows into explicitly chosen DTO values while preserving the ORM's page metadata. The mapper selects stored fields/getters; no persisted model is automatically exposed. Failure returns a zero page.
func MapSimplePage ¶
func MapSimplePage[From, To any](ctx context.Context, page orm.SimplePage[From], mapper func(From) (To, error)) (orm.SimplePage[To], error)
MapSimplePage retains count-free metadata. It never adds a total or page count.
func MessageDefinitions ¶
func MessageDefinitions() []i18n.MessageDefinition
MessageDefinitions declares the pagination labels for a catalog, beside validation.MessageDefinitions and http.MessageDefinitions. Configured applications register them automatically.
func NumberedJSON ¶
NumberedJSON composes an explicitly declared item DTO with the framework's numbered response. The template's Go fields/tags own its property names; item fields and codecs remain owned by the supplied typed JSON descriptor.
func SimpleJSON ¶
SimpleJSON retains the count-free response shape and the concrete item DTO.
func URL ¶ added in v0.3.0
func URL[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response], ctx context.Context, path P, filters F, page W) (string, error)
URL builds a page URL from concrete route, filter and ORM request values. It uses the same query codecs/default declarations as the handler boundary and never derives an origin from an arbitrary incoming request Host.
func ValidateAuthenticated ¶ added in v0.2.0
func ValidateFilters ¶ added in v0.2.0
func ValidateFilters[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response], rules ...validation.Rule[F]) pageEndpoint[P, F, W, Page, Response]
ValidateFilters reuses generated field rules without adding a synthetic 'filters' prefix to actual query names or exported validation metadata.
func ValidatePath ¶ added in v0.2.0
func ValidatePath[P, F, W, Page, Response any](e pageEndpoint[P, F, W, Page, Response], rules ...validation.Rule[P]) pageEndpoint[P, F, W, Page, Response]
Types ¶
type AuthenticatedCursorEndpoint ¶
type AuthenticatedCursorEndpoint[P, F, M, A, T any] = authenticatedPageEndpoint[P, F, orm.CursorRequest[M], A, CursorResult[M, T], CursorResponse[T]]
AuthenticatedCursorEndpoint keeps cursor owner M, actor A and public DTO T distinct.
type AuthenticatedNumberedEndpoint ¶
type AuthenticatedNumberedEndpoint[P, F, A, T any] = authenticatedPageEndpoint[P, F, orm.PageRequest, A, orm.PageResult[T], NumberedResponse[T]]
AuthenticatedNumberedEndpoint supplies a concrete actor before a numbered page read.
type AuthenticatedSimpleEndpoint ¶
type AuthenticatedSimpleEndpoint[P, F, A, T any] = authenticatedPageEndpoint[P, F, orm.PageRequest, A, orm.SimplePage[T], SimpleResponse[T]]
AuthenticatedSimpleEndpoint is the count-free authenticated page contract.
type Config ¶
type Config struct {
NumberParam, SizeParam string
DefaultSize, MaximumSize int
MaximumPage int
Links LinkMode
EdgeLinks bool
PageWindow int
}
Config owns wire names, defaults and a maximum size no greater than the ORM's shared bound. Explicit names permit independent paginators without implicit bracket/nesting conventions. Values are rejected, never silently clamped. MaximumPage bounds numbered/simple offset depth so a client cannot request an arbitrarily expensive OFFSET; zero selects DefaultMaximumPage. Deeper pages fail query validation and navigation omits links beyond the bound. Use cursor pagination for unbounded traversal.
EdgeLinks adds first and, for numbered pages, last links. PageWindow lists up to that many numbered pages on each side of the current page with their links (at most MaximumPageWindow); simple pages have no count and ignore it. Both are off by default and absent from the wire when disabled.
func DefaultConfig ¶
func DefaultConfig() Config
type CursorConfig ¶
type CursorConfig struct {
AfterParam, BeforeParam, SizeParam string
DefaultSize, MaximumSize int
Links LinkMode
}
CursorConfig declares two exclusive directions and a bounded page size. The endpoint's ordinary total query-byte limit still applies to cursor tokens.
func DefaultCursorConfig ¶
func DefaultCursorConfig() CursorConfig
func (CursorConfig) Validate ¶
func (c CursorConfig) Validate() error
type CursorEndpoint ¶
type CursorEndpoint[P, F, M, T any] = pageEndpoint[P, F, orm.CursorRequest[M], CursorResult[M, T], CursorResponse[T]]
CursorEndpoint preserves source owner M separately from public DTO T.
func DefineCursor ¶
func DefineCursor[M, P, F, T any](route foundryhttp.Route[P], filters foundryhttp.Query[F], item contract.JSON[T], config CursorConfig, options ...foundryhttp.EndpointOption) CursorEndpoint[P, F, M, T]
DefineCursor declares pagination over model or projection M. Supply M explicitly; the route, generated filters and item descriptor infer the other concrete types. Query execution still validates each token's query scope and authorization must run for every request. Tokens are positions, not signed/encrypted credentials.
type CursorMeta ¶
type CursorMeta struct {
Size int `json:"per_page"`
}
CursorMeta reports page size only; cursor pagination does not count totals.
type CursorRequest ¶
type CursorRequest[P, F, M any] = pageRequest[P, F, orm.CursorRequest[M]]
CursorRequest retains the original model/projection owner in its ORM request. After and Before contain cursor positions, not credentials or authorization.
type CursorResponse ¶
type CursorResponse[T any] struct { Data []T `json:"data"` Meta CursorMeta `json:"meta"` Links Links `json:"links"` }
CursorResponse contains explicit DTOs and source-owned navigation serialized through endpoint URLs. Its data is always an array; empty pages have no links.
type CursorResult ¶
type CursorResult[M, T any] struct { // contains filtered or unexported fields }
CursorResult retains a source-owned navigation position alongside explicit DTO values. MapCursorPage is its constructor; the zero value is invalid. Its private metadata preserves the validated ORM result without retaining original model rows or manufacturing cursors for the DTO type.
func MapCursorPage ¶
func MapCursorPage[M, T any](ctx context.Context, page orm.CursorPage[M], mapper func(M) (T, error)) (CursorResult[M, T], error)
MapCursorPage selects DTO values while preserving the source's cursor owner, validated size and navigation. It never invokes a getter implicitly. Failure returns an invalid zero result and the same callback ownership as MapPage.
func (CursorResult[M, T]) Items ¶
func (p CursorResult[M, T]) Items() []T
func (CursorResult[M, T]) Previous ¶
func (p CursorResult[M, T]) Previous() value.Optional[orm.Cursor[M]]
func (CursorResult[M, T]) Size ¶
func (p CursorResult[M, T]) Size() int
type Links ¶
type Links struct {
Next value.Nullable[string] `json:"next"`
Previous value.Nullable[string] `json:"prev"`
First value.Optional[string] `json:"first,omitzero"`
Last value.Optional[string] `json:"last,omitzero"`
Window []PageLink `json:"window,omitzero"`
}
Links contains optional next/previous URLs. A link is a navigation hint, not a guarantee that data will still exist when another request is executed. First, Last and Window are opt-in (Config.EdgeLinks, Config.PageWindow) and omitted from the wire when disabled; cursor pages never carry them. Last and Window need a count, so only numbered pages carry them. No link points beyond Config.MaximumPage.
type NumberedEndpoint ¶
type NumberedEndpoint[P, F, T any] = pageEndpoint[P, F, orm.PageRequest, orm.PageResult[T], NumberedResponse[T]]
NumberedEndpoint receives typed page input and expects an ORM page of explicit response DTOs. Handle supplies metadata and navigation before JSON encoding.
func DefineNumbered ¶
func DefineNumbered[P, F, T any](route foundryhttp.Route[P], filters foundryhttp.Query[F], item contract.JSON[T], config Config, options ...foundryhttp.EndpointOption) NumberedEndpoint[P, F, T]
DefineNumbered composes generated filters, defaulted pagination and a declared item DTO. The endpoint accepts no request body; ordinary route/method rules apply. Config.Links=PublicLinks requires PublicURLs; ApplyMiddleware rejects a router whose PublicLinks routes are not covered by it.
type NumberedMeta ¶
type NumberedMeta struct {
Number int `json:"current_page"`
Size int `json:"per_page"`
Total int64 `json:"total"`
Pages int64 `json:"last_page"`
}
NumberedMeta preserves the ORM's exact numbered-page metadata, including zero last_page for an empty count. Separate count/read operations are not a snapshot.
type NumberedResponse ¶
type NumberedResponse[T any] struct { Data []T `json:"data"` Meta NumberedMeta `json:"meta"` Links Links `json:"links"` }
NumberedResponse contains explicit DTO values and shared page metadata.
type Parameters ¶
type Parameters[F any] = parameters[F, orm.PageRequest]
Parameters retains generated domain filters and the actual ORM request.
type Request ¶
type Request[P, F any] = pageRequest[P, F, orm.PageRequest]
Request is the thin domain-handler input, with concrete path/filter types. Page is usable directly by an ORM query's Paginate or SimplePaginate method.
type SimpleEndpoint ¶
type SimpleEndpoint[P, F, T any] = pageEndpoint[P, F, orm.PageRequest, orm.SimplePage[T], SimpleResponse[T]]
SimpleEndpoint is the corresponding count-free transport contract.
func DefineSimple ¶
func DefineSimple[P, F, T any](route foundryhttp.Route[P], filters foundryhttp.Query[F], item contract.JSON[T], config Config, options ...foundryhttp.EndpointOption) SimpleEndpoint[P, F, T]
DefineSimple creates the same thin handler boundary without a count query or fabricated total metadata. Handlers return orm.SimplePage[T].
type SimpleMeta ¶
type SimpleMeta struct {
Number int `json:"current_page"`
Size int `json:"per_page"`
HasMore bool `json:"has_more"`
}
SimpleMeta retains navigation information without claiming a total count.
type SimpleResponse ¶
type SimpleResponse[T any] struct { Data []T `json:"data"` Meta SimpleMeta `json:"meta"` Links Links `json:"links"` }
SimpleResponse contains explicit DTO values and count-free metadata.