Skip to content

Cookies

type ListIn struct {
Pagination // embedded structs are flattened
Q string `query:"q"`
Since time.Time `query:"since"` // RFC 3339
Tenant string `header:"X-Tenant" required:"true"`
}
type Pagination struct {
Offset int `query:"offset" default:"0"`
Limit int `query:"limit" default:"20"`
}
type CreateIn struct {
Body struct {
Email string `json:"email"`
} `body:"json"` // also body:"form", body:"raw"
}
type UploadIn struct {
Title string `form:"title"`
File *multipart.FileHeader `file:"file"`
}
Tag From
path:"id" path wildcard (always required)
query:"q" query string; slices for repeated keys; pointers for optional
header:"X-Tenant" request header
cookie:"sid" cookie value, or *http.Cookie
form:"name", file:"f" multipart or urlencoded form
body:"json" / "form" / "raw" request body
default:"10", required:"true" modifiers

Types: strings, bools, ints, uints, floats, time.Time, time.Duration, anything implementing encoding.TextUnmarshaler, and types registered with dygo.RegisterConverter. Custom sources: dygo.RegisterSource("user", fn) then User *User \user:“”``.

An empty value (?limit=) counts as missing, so default applies. Every bad field is reported in one 400:

{"statusCode":400,"error":"Bad Request","message":"invalid request",
"details":[{"source":"path","name":"id","value":"zzz","reason":"must be 16 hex characters"}]}
  • Any value: JSON. string: text/plain. []byte: octet-stream. dygo.NoContent{}: 204.
  • dygo.Stream(reader, contentType), dygo.File(path), dygo.SSE(seq), dygo.RedirectTo(url, code).
  • Inside a handler: dygo.SetStatus(ctx, 202), dygo.SetHeader(ctx, k, v), dygo.SetCookie(ctx, c), dygo.Request(ctx), dygo.RouteOf(ctx).
  • Route options: dygo.HTTPCode(200), dygo.Header(k, v), dygo.Redirect(url, code), dygo.BodyLimit(n), dygo.StrictJSON(), dygo.RouteMiddleware(mw), dygo.Version("2"), and dygo.Options(...) to combine them.