Documentation
¶
Overview ¶
Package pagination provides wowapi's page/cursor response envelopes and the opaque keyset cursor used for feed-style listing. It is the kernel counterpart of the shapes documented in docs/blueprint/04 §4 (PageResponse, CursorPage) and the pagination half of docs/blueprint/05 §2 ("allowlist-driven; SQL injection impossible by construction").
A Cursor is an opaque, tamper-evident-by-decode-failure encoding of a keyset position — the physical column values of the last row returned. httpx's ParsePagination builds a Request from the raw per_page + cursor query params via Parse; the resulting Request carries a clamped Limit and the decoded Cursor. Attacker-supplied cursors that do not decode yield a KindValidation error and never panic.
The package name is pagination even though the blueprint refers to it as "page" in some signatures.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func EncodeCursor ¶
EncodeCursor encodes a keyset tuple (last-row column values) into an opaque cursor string. An empty/nil map encodes to "" (the zero cursor). An unsupported value type is a server-side programming error (the caller controls the keyset columns), so it is returned as a plain error, not a KindValidation.
func EncodeCursorWithSig ¶
EncodeCursorWithSig encodes a keyset tuple together with the signature of the sort it was minted under, so a later request can detect that the sort order changed (a direction flip or column reorder that the column-set check alone would miss — roadmap R7). An empty sig produces the legacy flat encoding, so this is a drop-in for EncodeCursor when no sort binding is desired.
Types ¶
type Cursor ¶
type Cursor struct {
// contains filtered or unexported fields
}
Cursor is an opaque keyset position: the physical column values of the last row returned, so the next query can resume with a WHERE (cols) > (values) comparison. It is encoded as base64url(JSON) and is deliberately not human-meaningful — clients round-trip it verbatim via CursorPage.NextCursor.
Supported scalar value types (encode → decode round-trip):
string → string bool → bool int/…/int64 → int64 (integer JSON numbers decode back to int64) uint/…/uint64 → int64 float32/float64 → float64 (fractional/exponent JSON numbers) uuid.UUID → string (canonical RFC 4122 form) time.Time → string (RFC 3339, nanosecond precision, UTC)
uuid.UUID and time.Time are normalised to their string forms on encode, so Values reports them as strings; that is sufficient to rebuild a keyset WHERE clause where the column type drives the parameter binding.
func DecodeCursor ¶
DecodeCursor parses an opaque cursor produced by EncodeCursor. An empty string decodes to the zero Cursor. Any malformed input — bad base64, non-object JSON, trailing data, or an oversized payload — yields a KindValidation error and never panics (this is attacker-reachable input).
func (Cursor) IsZero ¶
IsZero reports whether the cursor carries no position (start from the beginning).
type CursorPage ¶
type CursorPage[T any] struct { Items []T `json:"items"` NextCursor string `json:"next_cursor,omitempty"` HasMore bool `json:"has_more"` }
CursorPage is the cursor-page envelope (default for feeds/large lists). NextCursor is an opaque base64url(JSON) keyset position (see Cursor); it is omitted when there is no further page. See 04 §4.
type Defaults ¶
Defaults configures per_page clamping for Parse.
PerPage – page size used when the client omits per_page (or sends 0).
MaxPerPage – hard upper bound; requests above it are clamped down. A value
<= 0 disables the upper bound.
type PageResponse ¶
type PageResponse[T any] struct { Items []T `json:"items"` Page int `json:"page"` PerPage int `json:"per_page"` TotalCount int64 `json:"total_count,omitempty"` }
PageResponse is the offset-page envelope (admin/small lists). TotalCount is omitted from the wire when a COUNT would be too expensive. See 04 §4.
type Request ¶
Request is the parsed, validated pagination input for a list query: a page size clamped to [1, MaxPerPage] and the decoded keyset Cursor.
func Parse ¶
Parse turns the raw per_page and cursor query-parameter strings into a Request. per_page handling (documented contract):
"" → Defaults.PerPage "0" → Defaults.PerPage > Max → Defaults.MaxPerPage (when Max > 0) negative → KindValidation error non-int → KindValidation error
A malformed cursor yields a KindValidation error (see DecodeCursor); an empty cursor yields a zero Cursor (IsZero == true), i.e. "start from the beginning".