Documentation
¶
Overview ¶
Package order describes the ordering of a list query: a By value (an allowlisted field name + an ASC/DESC direction) and a Parse that builds one from untrusted "field,direction" request input.
Ordering is split across layers the same way pagination is. order owns the transport-agnostic value and its validation; the store owns the SQL — it maps the allowlisted field to a column and builds the ORDER BY clause, so the engine detail never leaks into the handler. Parse never copies raw input into By.Field: it only stores values drawn from the caller's allowlist, so the field is safe for the store to look up.
Usage ¶
// Domain layer: the allowlist of sortable fields and the default order.
var sortable = map[string]string{"created_at": "created_at", "name": "name"}
var def = order.NewBy("created_at", order.DESC)
// Handler: parse untrusted ?order_by=, mapping a bad field/direction to 400.
by, err := order.Parse(sortable, r.URL.Query().Get("order_by"), def)
if err != nil {
return errs.New(errs.InvalidArgument, err)
}
// Store: map the allowlisted field to a column and build the clause.
col := columns[by.Field] // a store-local field -> column map
clause := " ORDER BY " + col + " " + by.Direction + ", id " + by.Direction
Pair it with page (offset) or query for paginated listings. Cursor (keyset) pagination fixes its own order to match the cursor key, so order.By applies to offset queries.
Index ¶
Constants ¶
const ( ASC = "ASC" DESC = "DESC" )
Directions for data ordering.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type By ¶
By is a field to order by plus a direction. Field is an allowlisted name (not raw user input): Parse only ever sets it from a caller-supplied mapping, so it is safe for a store to interpolate into a column lookup. Direction is ASC or DESC.
func NewBy ¶
NewBy builds a By, defaulting an unknown direction to ASC. It performs no field validation — pair it with a fixed field name (e.g. a default order), or use Parse for untrusted input.
func Parse ¶
Parse builds a By from an untrusted "field[,direction]" string (e.g. "name,DESC"). allowed is the allowlist: it maps an accepted field name to the value stored in By.Field (often itself, or a domain key a store later maps to a column) — a field absent from allowed is rejected, so a client cannot order by an arbitrary column. An empty orderBy yields def. Direction defaults to ASC and must be ASC or DESC.