Documentation
¶
Overview ¶
Package r3url provides bidirectional conversion between r3 query types and URL query parameters.
Category: Serialization dialect.
It supports two parsing modes:
- Unified mode: the entire query is passed as a single JSON parameter (?query={...}), using the same schema as the r3json dialect.
- Decomposed mode: each r3 component is a separate URL parameter (?fields=a,b&filters=[...]&sort=name:asc&page=2&page_size=25).
The default behavior (ModeAuto) automatically detects which mode to use: if a "query" parameter is present, unified mode is used; otherwise, decomposed mode.
All parameter names, sort formats, and filter styles are configurable via functional options. Django-style shorthand filters (?status=active&age__gte=18) are supported as an opt-in feature.
Index ¶
- Variables
- func FormatCursorPagination(c *r3.CursorSpec, paramNames ParamNames) url.Values
- func FormatDjangoFilters(filters r3.Filters, cfg Config) url.Values
- func FormatFields(fields r3.Fields) string
- func FormatFilters(filters r3.Filters) (string, error)
- func FormatPagination(p *r3.PaginationSpec, paramNames ParamNames) url.Values
- func FormatQuery(q r3.Query, opts ...Option) (url.Values, error)
- func FormatSort(sorts r3.Sorts, format SortFormat) (string, error)
- func IsErrDialectorFailure(err error) bool
- func ParseCursorPagination(values url.Values, paramNames ParamNames) (*r3.CursorSpec, error)
- func ParseDjangoFilters(values url.Values, cfg Config) (r3.Filters, error)
- func ParseFields(raw string) (r3.Fields, error)
- func ParseFilters(raw string) (r3.Filters, error)
- func ParsePagination(values url.Values, paramNames ParamNames) (*r3.PaginationSpec, error)
- func ParseQuery(values url.Values, opts ...Option) (r3.Query, error)
- func ParseSort(raw string, format SortFormat) (r3.Sorts, error)
- type Config
- type FilterConfig
- type Mode
- type Option
- type ParamNames
- type SortConfig
- type SortFormat
Constants ¶
This section is empty.
Variables ¶
var ErrURLDialectorFailed = errors.New("url dialector failed")
ErrURLDialectorFailed is a generic error for r3url dialector failures.
Functions ¶
func FormatCursorPagination ¶
func FormatCursorPagination(c *r3.CursorSpec, paramNames ParamNames) url.Values
FormatCursorPagination writes cursor pagination parameters into url.Values. If cursor is nil, no parameters are added.
func FormatDjangoFilters ¶
FormatDjangoFilters formats r3.Filters as Django-style URL parameters. Only simple filters (non-AND/OR) can be represented in Django-style. Filters with AND/OR groups are silently skipped.
func FormatFields ¶
FormatFields formats r3.Fields into a comma-separated string. Example: Fields{FieldSpec("id"), FieldSpec("name")} -> "id,name".
func FormatFilters ¶
FormatFilters formats r3.Filters into a JSON string.
func FormatPagination ¶
func FormatPagination(p *r3.PaginationSpec, paramNames ParamNames) url.Values
FormatPagination writes pagination parameters into url.Values. If pagination is nil, no parameters are added.
func FormatQuery ¶
FormatQuery formats an r3.Query into url.Values using the configured mode and options.
In ModeAuto, it defaults to decomposed mode for formatting (since decomposed produces more human-readable URLs). Use WithMode(ModeUnified) to format as a single JSON query parameter instead.
Example usage:
values, err := r3url.FormatQuery(q)
// values.Encode() -> "fields=id,name&sort=name:asc&page=1&page_size=25"
values, err := r3url.FormatQuery(q, r3url.WithMode(r3url.ModeUnified))
// values.Encode() -> "query={...json...}"
func FormatSort ¶
func FormatSort(sorts r3.Sorts, format SortFormat) (string, error)
FormatSort formats r3.Sorts into a string using the specified format.
func IsErrDialectorFailure ¶
IsErrDialectorFailure checks if the given error is a r3url failure.
func ParseCursorPagination ¶
func ParseCursorPagination(values url.Values, paramNames ParamNames) (*r3.CursorSpec, error)
ParseCursorPagination extracts cursor pagination parameters from url.Values. It reads the after, before, and limit parameters using the configured param names.
If no cursor parameters are present, it returns nil (no cursor pagination requested).
func ParseDjangoFilters ¶
ParseDjangoFilters parses Django-style query parameters into r3.Filters.
Django-style parameters use the pattern "field__operator=value":
?status=active -> {f: "status", op: "eq", v: "active"}
?age__gte=18 -> {f: "age", op: "gte", v: "18"}
?name__like=John% -> {f: "name", op: "like", v: "John%"}
?tags__in=a,b,c -> {f: "tags", op: "in", v: ["a","b","c"]}
Parameters without the separator are treated as "eq" filters. Reserved parameter names (fields, filters, sort, page, page_size, query) are skipped.
The cfg.DjangoFields whitelist controls which fields are allowed. If it is empty, all fields are allowed (validated for identifier safety).
func ParseFields ¶
ParseFields parses a comma-separated string of field names into r3.Fields. Example: "id,name,status" -> Fields{FieldSpec("id"), FieldSpec("name"), FieldSpec("status")}
Empty string returns nil (no fields specified).
func ParseFilters ¶
ParseFilters parses a JSON-encoded filter string into r3.Filters. The string should be a JSON array of filter objects using the r3json schema.
Example: [{"f":"status","op":"eq","v":"active"},{"f":"age","op":"gte","v":18}]
Empty string returns nil (no filters specified).
func ParsePagination ¶
func ParsePagination(values url.Values, paramNames ParamNames) (*r3.PaginationSpec, error)
ParsePagination extracts pagination parameters from url.Values. It reads the page number and page size parameters using the configured param names.
If neither parameter is present, it returns nil (no pagination specified).
func ParseQuery ¶
ParseQuery parses url.Values into an r3.Query using the configured mode and options.
In ModeAuto (default), it checks for the unified "query" parameter first. If present, unified mode is used; otherwise, decomposed mode is used.
Example usage:
// Auto mode (default):
q, err := r3url.ParseQuery(r.URL.Query())
// Decomposed with sign-prefix sort:
q, err := r3url.ParseQuery(r.URL.Query(),
r3url.WithMode(r3url.ModeDecomposed),
r3url.WithSortFormat(r3url.SortFormatSignPrefix),
)
// With Django-style filters:
q, err := r3url.ParseQuery(r.URL.Query(),
r3url.WithDjangoStyleFilters("status", "age", "name"),
)
Types ¶
type Config ¶
type Config struct {
// Mode determines the parsing strategy. Default: ModeAuto.
Mode Mode
// ParamNames customizes the URL parameter names.
ParamNames ParamNames
// Sort configures sort parsing and formatting.
Sort SortConfig
// Filter configures filter parsing.
Filter FilterConfig
}
Config controls how the URL dialect parses and formats query parameters.
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns a Config with sensible defaults.
type FilterConfig ¶
type FilterConfig struct {
// AllowDjangoStyle enables parsing field__op=value query parameters as filters.
// Default: false.
AllowDjangoStyle bool
// DjangoSeparator is the separator between field name and operator in Django-style params.
// Default: "__" (double underscore).
DjangoSeparator string
// DjangoFields restricts which fields can be used in Django-style filters.
// If empty and AllowDjangoStyle is true, all fields are allowed (validated for identifier safety).
// Setting this is recommended as a security safeguard to prevent arbitrary query parameters
// from being interpreted as filters.
DjangoFields []string
}
FilterConfig configures filter parsing.
type Mode ¶
type Mode int
Mode determines the parsing/formatting strategy for URL query parameters.
const ( // ModeAuto tries unified mode first (if the "query" param is present), // and falls back to decomposed mode otherwise. This is the default. ModeAuto Mode = iota // ModeUnified only accepts a single JSON parameter containing the full query. ModeUnified // ModeDecomposed only accepts decomposed parameters (fields, filters, sort, page, page_size). ModeDecomposed )
type Option ¶
type Option func(*Config)
Option is a functional option for configuring the URL dialect.
func WithDjangoSeparator ¶
WithDjangoSeparator sets the separator used in Django-style filter parameters. Default is "__" (double underscore).
func WithDjangoStyleFilters ¶
WithDjangoStyleFilters enables Django-style filter parsing for the specified fields. If no fields are provided, all fields are allowed (not recommended for security reasons).
func WithParamNames ¶
func WithParamNames(p ParamNames) Option
WithParamNames sets custom parameter names.
type ParamNames ¶
type ParamNames struct {
// Query is the parameter name for unified mode. Default: "query".
Query string
// Fields is the parameter name for the fields list. Default: "fields".
Fields string
// Filters is the parameter name for the filters JSON array. Default: "filters".
Filters string
// Sort is the parameter name for the sort specification. Default: "sort".
Sort string
// PageNum is the parameter name for the page number. Default: "page".
PageNum string
// PageSize is the parameter name for the page size. Default: "page_size".
PageSize string
// CursorAfter is the parameter name for forward cursor token. Default: "after".
CursorAfter string
// CursorBefore is the parameter name for backward cursor token. Default: "before".
CursorBefore string
// CursorLimit is the parameter name for cursor page size. Default: "limit".
CursorLimit string
}
ParamNames allows customizing the URL parameter names used during parsing and formatting.
func DefaultParamNames ¶
func DefaultParamNames() ParamNames
DefaultParamNames returns parameter names with sensible defaults.
type SortConfig ¶
type SortConfig struct {
// Format controls how sort is parsed/formatted. Default: SortFormatColonDir.
Format SortFormat
}
SortConfig configures sort parsing and formatting.
type SortFormat ¶
type SortFormat int
SortFormat controls how sort parameters are parsed and formatted.
const ( // SortFormatColonDir uses "field:direction" pairs separated by commas. // Example: "name:asc,age:desc" // Nulls position can be appended: "name:asc:nulls_last". SortFormatColonDir SortFormat = iota // SortFormatSignPrefix uses a "-" prefix for descending, no prefix for ascending. // Example: "name,-age" // This format does not support nulls position. SortFormatSignPrefix // SortFormatJSON parses the sort parameter as a JSON array of sort objects, // using the same schema as the r3json dialect. // Example: [{"field":"name","direction":"asc"}]. SortFormatJSON )