Documentation
¶
Index ¶
- Variables
- func ContextWithLogger(ctx context.Context, l *slog.Logger) context.Context
- func LoggerFromContext(ctx context.Context) *slog.Logger
- type BindJSONOptions
- type Ctx
- type DefaultContext
- func (c *DefaultContext) BindAny(v any, opts ...BindJSONOptions) error
- func (c *DefaultContext) BindForm(v any, opts ...BindJSONOptions) error
- func (c *DefaultContext) BindJSON(v any, opts ...BindJSONOptions) error
- func (c *DefaultContext) BindMap(v any, m map[string]any, opts ...BindJSONOptions) error
- func (c *DefaultContext) BindPath(v any, opts ...BindJSONOptions) error
- func (c *DefaultContext) BindQuery(v any, opts ...BindJSONOptions) error
- func (c *DefaultContext) Clone() Ctx
- func (c *DefaultContext) Context() context.Context
- func (c *DefaultContext) Finish()
- func (c *DefaultContext) Get(key any, def ...any) any
- func (c *DefaultContext) Header(key, value string)
- func (c *DefaultContext) JSON(v any) error
- func (c *DefaultContext) Method() string
- func (c *DefaultContext) Param(name string) string
- func (c *DefaultContext) ParamAlphaNum(name string) string
- func (c *DefaultContext) ParamBool(name string, def ...bool) bool
- func (c *DefaultContext) ParamFilename(name string) string
- func (c *DefaultContext) ParamFloat64(name string, def ...float64) float64
- func (c *DefaultContext) ParamInt(name string, def ...int) int
- func (c *DefaultContext) ParamInt64(name string, def ...int64) int64
- func (c *DefaultContext) ParamSafe(name string) string
- func (c *DefaultContext) ParamUint(name string, def ...uint) uint
- func (c *DefaultContext) Path() string
- func (c *DefaultContext) Query(key string) string
- func (c *DefaultContext) QueryAlphaNum(key string) string
- func (c *DefaultContext) QueryBool(key string, def ...bool) bool
- func (c *DefaultContext) QueryFilename(key string) string
- func (c *DefaultContext) QueryFloat64(key string, def ...float64) float64
- func (c *DefaultContext) QueryInt(key string, def ...int) int
- func (c *DefaultContext) QueryInt64(key string, def ...int64) int64
- func (c *DefaultContext) QuerySafe(key string) string
- func (c *DefaultContext) QueryUint(key string, def ...uint) uint
- func (c *DefaultContext) Request() *http.Request
- func (c *DefaultContext) Reset(w http.ResponseWriter, r *http.Request, ps router.Params, route string)
- func (c *DefaultContext) ResponseWriter() http.ResponseWriter
- func (c *DefaultContext) Route() string
- func (c *DefaultContext) Send(status int, contentType string, b []byte) (int, error)
- func (c *DefaultContext) Set(key, value any) Ctx
- func (c *DefaultContext) SetJSONEscapeHTML(escape bool)
- func (c *DefaultContext) SetRequest(r *http.Request)
- func (c *DefaultContext) SetResponseWriter(w http.ResponseWriter)
- func (c *DefaultContext) Status(code int) Ctx
- func (c *DefaultContext) StatusCode() int
- func (c *DefaultContext) String(status int, body string) error
- func (c *DefaultContext) WroteHeader() bool
- type FieldError
- type FieldErrors
Constants ¶
This section is empty.
Variables ¶
var ( // ErrFieldUnexpected matches unknown/unexpected input fields. ErrFieldUnexpected error = fieldSentinel("unexpected") // ErrFieldInvalidType matches type mismatches without a known expected type. ErrFieldInvalidType error = fieldSentinel("invalid type") // ErrFieldTypeExpected matches any message that ends with " type expected" (e.g., "int type expected"). ErrFieldTypeExpected error = fieldSentinel("type expected") )
Sentinel errors to detect common field error categories with errors.Is.
These values enable ergonomic detection of field-level validation/binding issues returned by helpers (e.g., BindJSON, BindMap, BindAny). The messages of generated FieldErrors remain human-friendly (e.g., "unexpected", "invalid type", "int type expected"), while errors.Is can be used to check categories.
Example (categorizing field errors):
var fe ctx.FieldErrors
if errors.As(err, &fe) {
if errors.Is(fe, ctx.ErrFieldUnexpected) {
// Unknown input keys were present
}
if errors.Is(fe, ctx.ErrFieldTypeExpected) {
// At least one field has a precise expected-type message
}
}
Example (surface messages to clients):
var fe ctx.FieldErrors
if errors.As(err, &fe) {
out := map[string]string{}
for _, e := range fe.All() {
out[e.Field()] = e.Message() // e.g., {"age":"int type expected"}
}
_ = out
}
Functions ¶
func ContextWithLogger ¶
ContextWithLogger returns a new context carrying the provided slog.Logger.
Attach a request-scoped logger in middleware and retrieve it later from the request context. When combined with ctx.Ctx, you can store the logger on the request using c.Set(key, value) or by replacing the underlying request with a derived context that includes the logger.
Typical middleware usage:
func LoggingMiddleware(next flash.Handler) flash.Handler {
return func(c ctx.Ctx) error {
l := slog.Default().With("req_id", c.Get("req_id"))
r := c.Request().WithContext(ctx.ContextWithLogger(c.Context(), l))
c.SetRequest(r)
return next(c)
}
}
In a handler:
func Show(c ctx.Ctx) error {
l := ctx.LoggerFromContext(c.Context())
l.Info("handling request", "path", c.Path())
return c.String(200, "ok")
}
func LoggerFromContext ¶
LoggerFromContext returns a slog.Logger from the context, or slog.Default if none is found.
This helper ensures handlers and middleware can always log even if a request-scoped logger was not injected. Prefer injecting a logger with ContextWithLogger so you can enrich it with request fields (request id, user id, route, etc.).
Example:
l := ctx.LoggerFromContext(c.Context())
l.Info("user fetched", "user_id", id)
Types ¶
type BindJSONOptions ¶
type BindJSONOptions struct {
// WeaklyTypedInput allows common type coercions, e.g., "10" -> 10 for int fields.
WeaklyTypedInput bool
// ErrorUnused when true returns an error for unexpected fields.
ErrorUnused bool
}
BindJSONOptions customizes how JSON and map binding decode payloads into structs.
Defaults when options are omitted:
- ErrorUnused = true (unknown fields cause an error)
- WeaklyTypedInput = false (no implicit type coercion)
If an options value is provided explicitly, its zero-values are honored as-is.
Example (strict decoding, reject unknown fields):
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
var u User
err := c.BindJSON(&u) // same as c.BindJSON(&u, BindJSONOptions{ErrorUnused: true})
if fe, ok := ctx.AsFieldErrors(err); ok {
// fe["extra"] == "unexpected field" when body contains unknown key "extra"
}
Example (allow coercion, allow unknown fields):
var u User
_ = c.BindJSON(&u, BindJSONOptions{WeaklyTypedInput: true, ErrorUnused: false})
type Ctx ¶
type Ctx interface {
// Request/Response accessors and mutators
// Request returns the underlying *http.Request associated with this context.
Request() *http.Request
// SetRequest replaces the underlying *http.Request on the context.
// Example: attach a new context value to the request.
//
// ctx := context.WithValue(c.Context(), key, value)
// c.SetRequest(c.Request().WithContext(ctx))
SetRequest(*http.Request)
// ResponseWriter returns the underlying http.ResponseWriter.
ResponseWriter() http.ResponseWriter
// SetResponseWriter replaces the underlying http.ResponseWriter.
SetResponseWriter(http.ResponseWriter)
// Basic request data
// Context returns the request-scoped context.Context.
Context() context.Context
// Method returns the HTTP method (e.g., "GET").
Method() string
// Path returns the raw request URL path.
Path() string
// Route returns the route pattern (e.g., "/users/:id") when available.
Route() string
// Param returns a path parameter by name ("" if not present).
// Example: for route "/users/:id", Param("id") => "42".
Param(name string) string
// Query returns a query string parameter by key ("" if not present).
// Example: for "/items?sort=asc", Query("sort") => "asc".
Query(key string) string
// Typed path parameter helpers with optional defaults
ParamInt(name string, def ...int) int
ParamInt64(name string, def ...int64) int64
ParamUint(name string, def ...uint) uint
ParamFloat64(name string, def ...float64) float64
ParamBool(name string, def ...bool) bool
// Typed query parameter helpers with optional defaults
QueryInt(key string, def ...int) int
QueryInt64(key string, def ...int64) int64
QueryUint(key string, def ...uint) uint
QueryFloat64(key string, def ...float64) float64
QueryBool(key string, def ...bool) bool
// Secure parameter helpers with input validation and sanitization
ParamSafe(name string) string // HTML-escaped parameter
QuerySafe(key string) string // HTML-escaped query parameter
ParamAlphaNum(name string) string // Alphanumeric-only parameter
QueryAlphaNum(key string) string // Alphanumeric-only query parameter
ParamFilename(name string) string // Safe filename parameter (no path traversal)
QueryFilename(key string) string // Safe filename query parameter
// Response helpers
// Header sets a response header key/value.
Header(key, value string)
// Status stages the HTTP status code to be written; returns the Ctx to allow chaining.
// Example: c.Status(http.StatusCreated).JSON(obj)
Status(code int) Ctx
// StatusCode returns the status that will be written (or 200 after header write, or 0 if unset).
StatusCode() int
// JSON serializes v to JSON and writes it with an appropriate Content-Type.
// If Status() was not set, it defaults to 200.
JSON(v any) error
// String writes a text/plain body with the provided status code.
String(status int, body string) error
// Send writes raw bytes with a specific status and content type.
Send(status int, contentType string, b []byte) (int, error)
// WroteHeader reports whether the header has already been written to the client.
WroteHeader() bool
// BindJSON decodes request body JSON into v with strict defaults; see BindJSONOptions.
BindJSON(v any, opts ...BindJSONOptions) error
// BindMap binds from a generic map (e.g. collected from body/query/path) into v using mapstructure.
// Options mirror BindJSONOptions.
BindMap(v any, m map[string]any, opts ...BindJSONOptions) error
// BindForm collects form body fields and binds them into v (application/x-www-form-urlencoded or multipart/form-data).
BindForm(v any, opts ...BindJSONOptions) error
// BindQuery collects query string parameters and binds them into v.
BindQuery(v any, opts ...BindJSONOptions) error
// BindPath collects path parameters and binds them into v.
BindPath(v any, opts ...BindJSONOptions) error
// BindAny collects from path, body (json/form), and query according to priority and binds them into v.
BindAny(v any, opts ...BindJSONOptions) error
// Utilities
// Get retrieves a value from the request context by key, with optional default.
Get(key any, def ...any) any
// Set stores a value into a derived request context and replaces the underlying request.
Set(key, value any) Ctx
// Clone returns a shallow copy of the context suitable for use in a separate goroutine.
Clone() Ctx
}
Ctx is the request/response context interface exposed to handlers and middleware. It is implemented by *DefaultContext and lives in package ctx to avoid adapters and import cycles.
A Ctx provides convenient accessors for request data (method, path, params, query), helpers for retrieving typed parameters, and response helpers for writing headers and bodies in common formats.
Typical usage inside a handler:
c.GET("/users/:id", func(c ctx.Ctx) error {
// Basic request information
method := c.Method() // "GET"
route := c.Route() // "/users/:id"
path := c.Path() // e.g. "/users/42"
id := c.ParamInt("id", 0) // 42 (with default if parse fails)
page := c.QueryInt("page", 1) // from query string, default 1
_ = method; _ = route; _ = path; _ = id; _ = page
// Set a header and send JSON response
c.Header("X-Handler", "users-show")
return c.Status(http.StatusOK).JSON(map[string]any{"id": id})
})
Concurrency: Ctx is not safe for concurrent writes to the underlying http.ResponseWriter. Use Clone() and swap the writer if responding from another goroutine.
type DefaultContext ¶
type DefaultContext struct {
// contains filtered or unexported fields
}
DefaultContext is the concrete implementation of Ctx used by goflash. It wraps the http.ResponseWriter and *http.Request, exposes convenience helpers, and tracks route, status, and response state for each request.
Handlers generally accept the interface type (ctx.Ctx), not *DefaultContext, to allow substituting alternative implementations if desired.
func (*DefaultContext) BindAny ¶
func (c *DefaultContext) BindAny(v any, opts ...BindJSONOptions) error
BindAny merges values from query, body (Form then JSON), and path, and binds them into v. Precedence (highest wins): Path > Body > Query, and within Body: JSON > Form.
This is convenient for handlers that accept input from multiple sources while maintaining a single struct definition.
Examples:
// Route: /users/:id
// Request: GET /users/10?active=true
// Body: {"name":"Ada"}
type In struct {
ID int `json:"id"`
Name string `json:"name"`
Active bool `json:"active"`
}
var in In
_ = c.BindAny(&in) // => ID=10 (path), Name="Ada" (json), Active=true (query)
// Form vs JSON precedence: JSON overrides Form for keys present in both
// Body: name="A" (form) and {"name":"B"} (json) => name becomes "B"
func (*DefaultContext) BindForm ¶
func (c *DefaultContext) BindForm(v any, opts ...BindJSONOptions) error
BindForm collects form body fields and binds them into v. Supports application/x-www-form-urlencoded and multipart/form-data (textual fields only).
For multipart/form-data, file uploads are ignored here; only textual values are bound.
Examples:
// Content-Type: application/x-www-form-urlencoded
// Body: name=Ada&age=33
type Form struct { Name string `json:"name"`; Age int `json:"age"` }
var f Form
_ = c.BindForm(&f)
// Multipart: text fields collected from r.MultipartForm.Value
_ = c.BindForm(&f)
func (*DefaultContext) BindJSON ¶
func (c *DefaultContext) BindJSON(v any, opts ...BindJSONOptions) error
BindJSON decodes the request body JSON into v.
When v is a pointer to a struct, you may pass BindJSONOptions to control strictness and coercion; otherwise, non-struct targets use the standard library's strict behavior with DisallowUnknownFields.
Default behavior (no options):
- Unknown fields are reported as field errors
- No weak typing (strings are not coerced into numbers, etc.)
Field error mapping: common json.Decoder errors are converted into user-friendly FieldErrors keyed by the offending json field.
Examples:
// 1) Strict struct binding
type Payload struct {
Age int `json:"age"`
}
var p Payload
if err := c.BindJSON(&p); err != nil {
// Unknown fields => field error: {"extra": "unexpected field"}
}
// 2) Permissive binding (coercion + allow unknown)
_ = c.BindJSON(&p, BindJSONOptions{WeaklyTypedInput: true, ErrorUnused: false})
// 3) Non-struct target (map or slice)
var m map[string]any
_ = c.BindJSON(&m) // uses DisallowUnknownFields and returns raw json errors
func (*DefaultContext) BindMap ¶
func (c *DefaultContext) BindMap(v any, m map[string]any, opts ...BindJSONOptions) error
BindMap binds fields from the provided map into v using mapstructure, honoring options. TagName is "json" for all binders to keep a single source-of-truth for names.
The map's keys must match the struct's `json` tag names (or field names if tag missing). Type conversion behavior is governed by BindJSONOptions.WeaklyTypedInput. Unknown key behavior is governed by BindJSONOptions.ErrorUnused.
Examples:
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
m := map[string]any{"id": "10", "name": "Ada"}
var u User
// Coerce string to int
_ = c.BindMap(&u, m, BindJSONOptions{WeaklyTypedInput: true})
// Strict mode rejects unknown fields
m2 := map[string]any{"id": 1, "name": "Ada", "extra": true}
if err := c.BindMap(&u, m2, BindJSONOptions{ErrorUnused: true}); err != nil {
// err can be converted to FieldErrors indicating "extra" is unexpected
}
func (*DefaultContext) BindPath ¶
func (c *DefaultContext) BindPath(v any, opts ...BindJSONOptions) error
BindPath collects path parameters and binds them into v. The keys correspond to route parameter names (e.g., ":id").
Example:
// Route: /users/:id
type P struct { ID int `json:"id"` }
var p P
_ = c.BindPath(&p)
func (*DefaultContext) BindQuery ¶
func (c *DefaultContext) BindQuery(v any, opts ...BindJSONOptions) error
BindQuery collects query string parameters and binds them into v. Only the first value per key is used, matching typical form semantics.
Example:
// GET /search?q=flash&page=2
type Q struct { Q string `json:"q"`; Page int `json:"page"` }
var q Q
_ = c.BindQuery(&q)
func (*DefaultContext) Clone ¶
func (c *DefaultContext) Clone() Ctx
Clone returns a shallow copy of the context. Safe for use across goroutines as long as the ResponseWriter is swapped to a concurrency-safe writer if needed.
func (*DefaultContext) Context ¶
func (c *DefaultContext) Context() context.Context
Context returns the request context.Context. It is the same as c.Request().Context().
func (*DefaultContext) Finish ¶
func (c *DefaultContext) Finish()
Finish is a hook for context cleanup after request handling. No-op by default. Frameworks may override or extend this method to release per-request resources.
func (*DefaultContext) Get ¶
func (c *DefaultContext) Get(key any, def ...any) any
Get returns a value from the request context by key. If the key is not present (or the stored value is nil), it returns the provided default when given (Get(key, def)), otherwise it returns nil.
Example:
type userKey struct{}
u := c.Get(userKey{}).(*User)
func (*DefaultContext) Header ¶
func (c *DefaultContext) Header(key, value string)
Header sets a header on the response. Has no effect after the header is written.
func (*DefaultContext) JSON ¶
func (c *DefaultContext) JSON(v any) error
JSON serializes the provided value as JSON and writes the response. If Status() has not been called yet, it defaults to 200 OK. Content-Type is set to "application/json; charset=utf-8" and Content-Length is calculated.
Example:
return c.Status(http.StatusCreated).JSON(struct{ ID int `json:"id"` }{ID: 1})
func (*DefaultContext) Method ¶
func (c *DefaultContext) Method() string
Method returns the HTTP method for the request (e.g., "GET").
func (*DefaultContext) Param ¶
func (c *DefaultContext) Param(name string) string
Param returns a path parameter by name. Returns "" if not found. Note: router.Params.ByName returns "" if not found, so this avoids extra allocation.
Example:
// Route: /posts/:slug
slug := c.Param("slug")
func (*DefaultContext) ParamAlphaNum ¶
func (c *DefaultContext) ParamAlphaNum(name string) string
ParamAlphaNum returns a path parameter containing only alphanumeric characters. Non-alphanumeric characters are stripped from the result.
Security: Prevents injection attacks by allowing only safe characters.
Example:
// Route: /users/:id
// URL: /users/abc123../../../etc/passwd
id := c.ParamAlphaNum("id") // Returns: "abc123"
func (*DefaultContext) ParamBool ¶
func (c *DefaultContext) ParamBool(name string, def ...bool) bool
ParamBool returns the named path parameter parsed as bool. Returns def on missing or parse error. Accepts the same forms as strconv.ParseBool: 1,t,T,TRUE,true,True, 0,f,F,FALSE,false,False.
func (*DefaultContext) ParamFilename ¶
func (c *DefaultContext) ParamFilename(name string) string
ParamFilename returns a path parameter as a safe filename. Only allows alphanumeric characters, dots, dashes, and underscores. Prevents path traversal attacks by removing directory separators.
Security: Prevents path traversal attacks and ensures safe filenames.
Example:
// Route: /files/:name
// URL: /files/../../../etc/passwd
name := c.ParamFilename("name") // Returns: "etcpasswd"
// URL: /files/document.pdf
name := c.ParamFilename("name") // Returns: "document.pdf"
func (*DefaultContext) ParamFloat64 ¶
func (c *DefaultContext) ParamFloat64(name string, def ...float64) float64
ParamFloat64 returns the named path parameter parsed as float64. Returns def (or 0) on missing or parse error.
func (*DefaultContext) ParamInt ¶
func (c *DefaultContext) ParamInt(name string, def ...int) int
ParamInt returns the named path parameter parsed as int. Returns def (or 0) on missing or parse error.
Example: c.ParamInt("id", 0) -> 42
func (*DefaultContext) ParamInt64 ¶
func (c *DefaultContext) ParamInt64(name string, def ...int64) int64
ParamInt64 returns the named path parameter parsed as int64. Returns def (or 0) on missing or parse error.
func (*DefaultContext) ParamSafe ¶
func (c *DefaultContext) ParamSafe(name string) string
ParamSafe returns a path parameter by name with HTML escaping to prevent XSS. This is useful when the parameter value will be displayed in HTML content.
Security: Prevents XSS attacks by escaping HTML special characters.
Example:
// Route: /users/:name
// URL: /users/<script>alert('xss')</script>
name := c.ParamSafe("name") // Returns: "<script>alert('xss')</script>"
func (*DefaultContext) ParamUint ¶
func (c *DefaultContext) ParamUint(name string, def ...uint) uint
ParamUint returns the named path parameter parsed as uint. Returns def (or 0) on missing or parse error.
func (*DefaultContext) Path ¶
func (c *DefaultContext) Path() string
Path returns the request URL path (raw path without scheme/host).
func (*DefaultContext) Query ¶
func (c *DefaultContext) Query(key string) string
Query returns a query string parameter by key. Returns "" if not found. Note: url.Values.Get returns "" if not found, so this avoids extra allocation.
Example:
// URL: /search?q=flash
q := c.Query("q")
func (*DefaultContext) QueryAlphaNum ¶
func (c *DefaultContext) QueryAlphaNum(key string) string
QueryAlphaNum returns a query parameter containing only alphanumeric characters. Non-alphanumeric characters are stripped from the result.
Security: Prevents injection attacks by allowing only safe characters.
Example:
// URL: /search?category=books&sort=name';DROP TABLE users;--
sort := c.QueryAlphaNum("sort") // Returns: "nameDROPTABLEusers"
func (*DefaultContext) QueryBool ¶
func (c *DefaultContext) QueryBool(key string, def ...bool) bool
QueryBool returns the query parameter parsed as bool. Returns def (or false) on missing or parse error.
func (*DefaultContext) QueryFilename ¶
func (c *DefaultContext) QueryFilename(key string) string
QueryFilename returns a query parameter as a safe filename. Only allows alphanumeric characters, dots, dashes, and underscores. Prevents path traversal attacks by removing directory separators.
Security: Prevents path traversal attacks and ensures safe filenames.
Example:
// URL: /download?file=../../../etc/passwd
file := c.QueryFilename("file") // Returns: "etcpasswd"
// URL: /download?file=document.pdf
file := c.QueryFilename("file") // Returns: "document.pdf"
func (*DefaultContext) QueryFloat64 ¶
func (c *DefaultContext) QueryFloat64(key string, def ...float64) float64
QueryFloat64 returns the query parameter parsed as float64. Returns def (or 0) on missing or parse error.
func (*DefaultContext) QueryInt ¶
func (c *DefaultContext) QueryInt(key string, def ...int) int
QueryInt returns the query parameter parsed as int. Returns def (or 0) on missing or parse error.
func (*DefaultContext) QueryInt64 ¶
func (c *DefaultContext) QueryInt64(key string, def ...int64) int64
QueryInt64 returns the query parameter parsed as int64. Returns def (or 0) on missing or parse error.
func (*DefaultContext) QuerySafe ¶
func (c *DefaultContext) QuerySafe(key string) string
QuerySafe returns a query parameter by key with HTML escaping to prevent XSS. This is useful when the query parameter value will be displayed in HTML content.
Security: Prevents XSS attacks by escaping HTML special characters.
Example:
// URL: /search?q=<script>alert('xss')</script>
q := c.QuerySafe("q") // Returns: "<script>alert('xss')</script>"
func (*DefaultContext) QueryUint ¶
func (c *DefaultContext) QueryUint(key string, def ...uint) uint
QueryUint returns the query parameter parsed as uint. Returns def (or 0) on missing or parse error.
func (*DefaultContext) Request ¶
func (c *DefaultContext) Request() *http.Request
Request returns the underlying *http.Request. Use c.Context() to access the request-scoped context values.
func (*DefaultContext) Reset ¶
func (c *DefaultContext) Reset(w http.ResponseWriter, r *http.Request, ps router.Params, route string)
Reset prepares the context for a new request. Used internally by the framework. It swaps in the writer, request, params and route pattern, and clears any response state. Libraries and middleware should not need to call Reset.
Example:
// internal server code dctx.Reset(w, r, params, "/users/:id")
func (*DefaultContext) ResponseWriter ¶
func (c *DefaultContext) ResponseWriter() http.ResponseWriter
ResponseWriter returns the underlying http.ResponseWriter.
func (*DefaultContext) Route ¶
func (c *DefaultContext) Route() string
Route returns the route pattern for the current request, if known. For example, "/users/:id".
func (*DefaultContext) Send ¶
Send writes raw bytes with the given status and content type. If contentType is empty, no Content-Type header is set. Content-Length is set and the header is written once.
Example:
data := []byte("<xml>ok</xml>")
_, err := c.Send(http.StatusOK, "application/xml", data)
func (*DefaultContext) Set ¶
func (c *DefaultContext) Set(key, value any) Ctx
Set stores a value in the request context using the provided key and value. It replaces the request with a clone that carries the new context and returns the context for chaining.
Note: Prefer using a custom, unexported key type to avoid collisions.
Example:
type userKey struct{}
c.Set(userKey{}, currentUser)
func (*DefaultContext) SetJSONEscapeHTML ¶
func (c *DefaultContext) SetJSONEscapeHTML(escape bool)
SetJSONEscapeHTML controls whether JSON responses escape HTML characters. Default is true to match encoding/json defaults. Set to false when returning HTML-containing JSON that should not be escaped.
func (*DefaultContext) SetRequest ¶
func (c *DefaultContext) SetRequest(r *http.Request)
SetRequest replaces the underlying *http.Request. Commonly used to attach a derived context:
ctx := context.WithValue(c.Context(), key, value) c.SetRequest(c.Request().WithContext(ctx))
func (*DefaultContext) SetResponseWriter ¶
func (c *DefaultContext) SetResponseWriter(w http.ResponseWriter)
SetResponseWriter replaces the underlying http.ResponseWriter. This is rarely needed in application code, but useful for testing or when wrapping the writer with middleware.
func (*DefaultContext) Status ¶
func (c *DefaultContext) Status(code int) Ctx
func (*DefaultContext) StatusCode ¶
func (c *DefaultContext) StatusCode() int
StatusCode returns the status code that will be written. If not set yet and header hasn't been written, returns 0. If the header has already been written without an explicit status, returns 200.
func (*DefaultContext) String ¶
func (c *DefaultContext) String(status int, body string) error
String writes a plain text response with the given status and body. Sets Content-Type to "text/plain; charset=utf-8" and Content-Length accordingly.
Example:
return c.String(http.StatusOK, "pong")
func (*DefaultContext) WroteHeader ¶
func (c *DefaultContext) WroteHeader() bool
WroteHeader reports whether the response header has been written. After the header is written, changing headers or status has no effect.
type FieldError ¶
FieldError represents a validation or binding error for a specific field. Implementations provide a field path/name and a human-friendly message. The same information can be obtained via Error(), but Field()/Message() are convenient for structured handling in application code and for serializing field-specific errors in APIs.
Example (printing structured errors):
var fe ctx.FieldErrors
if errors.As(err, &fe) {
for _, e := range fe.All() {
log.Printf("%s -> %s", e.Field(), e.Message())
}
}
type FieldErrors ¶
type FieldErrors interface {
error
All() []FieldError
}
FieldErrors represents multiple field validation/binding errors for a single decoding/binding operation.
FieldErrors satisfies the error interface. It also implements Is to support errors.Is comparisons against the sentinel errors in this package.
Example (group handling and iteration):
var fe ctx.FieldErrors
if errors.As(err, &fe) {
if errors.Is(fe, ctx.ErrFieldUnexpected) {
// handle unexpected input fields collectively
}
for _, e := range fe.All() {
fmt.Println(e.Error()) // "field <name>: <message>"
}
}