Context API
5 minute read
The Context provides access to request/response and utility methods.
Context objects are pooled and reused. Never store references to Context beyond the request handler. Check Context Guide for details.
Request Information
URL Parameters
c.Param(key string) string
Returns URL parameter value from the route path.
// Route: /users/:id
userID := c.Param("id")
c.AllParams() map[string]string
Returns all URL path parameters as a map.
Query Parameters
c.Query(key string) string
c.QueryDefault(key, defaultValue string) string
c.AllQueries() map[string]string
// GET /search?q=golang&page=2
query := c.Query("q") // "golang"
page := c.QueryDefault("page", "1") // "2"
all := c.AllQueries() // map[string]string{"q": "golang", "page": "2"}
Form Data
c.FormValue(key string) string
c.FormValueDefault(key, defaultValue string) string
Returns form parameter from POST request body.
// POST with form data
username := c.FormValue("username")
role := c.FormValueDefault("role", "user")
Headers
c.Request.Header.Get(key string) string
c.RequestHeaders() map[string]string
c.ResponseHeaders() map[string]string
Request Binding
For full request binding (Bind, BindQuery, BindJSON, etc.), use the separate binding package. The router Context provides only strict JSON binding.
Strict JSON Binding
c.BindStrict(dst any, opt BindOptions) error
Binds JSON with strict validation:
- Rejects unknown fields (catches typos)
- Enforces size limits
- Distinguishes 400 (malformed) vs 422 (type errors)
var req CreateUserRequest
if err := c.BindStrict(&req, router.BindOptions{MaxBytes: 1 << 20}); err != nil {
return // Error response already written
}
Content Type Validation
c.RequireContentType(allowed ...string) bool
c.RequireContentTypeJSON() bool
if !c.RequireContentTypeJSON() {
return // 415 Unsupported Media Type already sent
}
Streaming
// Stream JSON array items
router.StreamJSONArray[T](c *Context, each func(T) error, maxItems int) error
// Stream NDJSON (newline-delimited JSON)
router.StreamNDJSON[T](c *Context, each func(T) error) error
err := router.StreamJSONArray(c, func(item User) error {
return processUser(item)
}, 10000) // Max 10k items
Response Methods
JSON Responses
c.JSON(code int, obj any) error
c.IndentedJSON(code int, obj any) error
c.PureJSON(code int, obj any) error // No HTML escaping
c.SecureJSON(code int, obj any, prefix ...string) error
c.ASCIIJSON(code int, obj any) error // All non-ASCII escaped
Other Formats
c.YAML(code int, obj any) error
c.String(code int, value string) error
c.Stringf(code int, format string, values ...any) error
c.HTML(code int, html string) error
Binary & Streaming
c.Data(code int, contentType string, data []byte) error
c.DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) error
File Serving
c.ServeFile(filepath string)
Status & No Content
c.Status(code int)
c.NoContent()
Error Responses
c.WriteErrorResponse(status int, message string)
c.NotFound()
c.MethodNotAllowed(allowed []string)
Headers
c.Header(key, value string)
Sets a response header with automatic security sanitization (newlines stripped).
URL Information
c.Hostname() string // Host without port
c.Port() string // Port number
c.Scheme() string // "http" or "https"
c.BaseURL() string // scheme + host
c.FullURL() string // Complete URL with query string
Client Information
c.ClientIP() string // Real client IP (respects trusted proxies)
c.ClientIPs() []string // All IPs from X-Forwarded-For chain
c.IsHTTPS() bool // Request over HTTPS
c.IsLocalhost() bool // Request from localhost
c.IsXHR() bool // XMLHttpRequest (AJAX)
c.Subdomains(offset ...int) []string
Content Type Detection
c.IsJSON() bool // Content-Type is application/json
c.IsXML() bool // Content-Type is application/xml or text/xml
c.AcceptsJSON() bool // Accept header includes application/json
c.AcceptsHTML() bool // Accept header includes text/html
Content Negotiation
c.Accepts(offers ...string) string
c.AcceptsCharsets(offers ...string) string
c.AcceptsEncodings(offers ...string) string
c.AcceptsLanguages(offers ...string) string
// Accept: application/json, text/html;q=0.9
best := c.Accepts("json", "html", "xml") // "json"
// Accept-Language: en-US, fr;q=0.8
lang := c.AcceptsLanguages("en", "fr", "de") // "en"
Caching
c.IsFresh() bool // Response still fresh in client cache
c.IsStale() bool // Client cache is stale
if c.IsFresh() {
c.Status(http.StatusNotModified) // 304
return
}
Redirects
c.Redirect(code int, location string)
c.Redirect(http.StatusFound, "/login")
c.Redirect(http.StatusMovedPermanently, "https://newdomain.com")
Cookies
c.SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
c.GetCookie(name string) (string, error)
File Uploads
c.File(name string) (*File, error)
c.Files(name string) ([]*File, error)
File methods:
file.Bytes() ([]byte, error)
file.Open() (io.ReadCloser, error)
file.Save(dst string) error
file.Ext() string
file, err := c.File("avatar")
if err != nil {
return c.JSON(400, map[string]string{"error": "avatar required"})
}
file.Save("./uploads/" + uuid.New().String() + file.Ext())
Middleware Control
c.Next() // Execute next handler in chain
c.Abort() // Stop handler chain
c.IsAborted() bool // Check if chain was aborted
Error Collection
c.Error(err error) // Collect error without writing response
c.Errors() []error // Get all collected errors
c.HasErrors() bool // Check if errors were collected
if err := validateUser(c); err != nil {
c.Error(err)
}
if err := validateEmail(c); err != nil {
c.Error(err)
}
if c.HasErrors() {
c.JSON(400, map[string]any{"errors": c.Errors()})
return
}
Context Access
c.RequestContext() context.Context // Request's context.Context
c.TraceContext() context.Context // OpenTelemetry trace context
c.Logger() *slog.Logger // Request-scoped logger
Tracing & Metrics
Tracing
c.TraceID() string
c.SpanID() string
c.Span() trace.Span
c.SetSpanAttribute(key string, value any)
c.AddSpanEvent(name string, attrs ...attribute.KeyValue)
Metrics
c.RecordMetric(name string, value float64, attributes ...attribute.KeyValue)
c.IncrementCounter(name string, attributes ...attribute.KeyValue)
c.SetGauge(name string, value float64, attributes ...attribute.KeyValue)
Versioning
c.Version() string // Current API version ("v1", "v2", etc.)
c.IsVersion(version string) bool
c.RoutePattern() string // Matched route pattern ("/users/:id")
Complete Example
func handler(c *router.Context) {
// Parameters
id := c.Param("id")
query := c.Query("q")
// Headers
auth := c.Request.Header.Get("Authorization")
c.Header("X-Custom", "value")
// Strict binding (for full binding, use binding package)
var req CreateRequest
if err := c.BindStrict(&req, router.BindOptions{MaxBytes: 1 << 20}); err != nil {
return // Error response already written
}
// Tracing
c.SetSpanAttribute("user.id", id)
// Logging
c.Logger().Info("processing request", "user_id", id)
// Response
if err := c.JSON(200, map[string]string{
"id": id,
"query": query,
}); err != nil {
c.Logger().Error("failed to write response", "error", err)
}
}
Next Steps
- API Reference: See core types
- Context Guide: Learn about Context usage
- Binding Package: For full request binding, see binding package
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.