order

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 2, 2026 License: MIT Imports: 2 Imported by: 0

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

View Source
const (
	ASC  = "ASC"
	DESC = "DESC"
)

Directions for data ordering.

Variables

This section is empty.

Functions

This section is empty.

Types

type By

type By struct {
	Field     string
	Direction string
}

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

func NewBy(field string, direction string) By

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

func Parse(allowed map[string]string, orderBy string, def By) (By, error)

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.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL