Documentation
¶
Overview ¶
Package handler provides the core types that route handlers interact with.
The two primary exports are:
- HandlerFunc — the function signature for all route handlers.
- Context — an enriched request context that wraps http.ResponseWriter and *http.Request and provides helpers for reading inputs and writing outputs.
Unlike frameworks that hide net/http, gocore exposes the raw Writer and Request fields so that existing net/http middleware and libraries continue to work without adaptation.
Index ¶
- func GetClaims(r *http.Request) *auth.Claims
- func Release(ctx *Context)
- func SetClaims(r *http.Request, c *auth.Claims) *http.Request
- func SetParams(r *http.Request, p Params) *http.Request
- type Context
- func (c *Context) AddHeader(key, value string)
- func (c *Context) BadRequest(message string)
- func (c *Context) BindJSON(dst any) error
- func (c *Context) Blob(statusCode int, contentType string, data []byte)
- func (c *Context) BodyBytes() ([]byte, error)
- func (c *Context) Claims() *auth.Claims
- func (c *Context) ClientIP() string
- func (c *Context) Conflict(message string)
- func (c *Context) ContentType() string
- func (c *Context) Created(data any)
- func (c *Context) Fail(statusCode int, code, message string, details any)
- func (c *Context) Forbidden(message string)
- func (c *Context) Get(key string) (any, bool)
- func (c *Context) HTML(statusCode int, body string)
- func (c *Context) Header(name string) string
- func (c *Context) InternalServerError(message string)
- func (c *Context) JSON(statusCode int, v any)
- func (c *Context) Logger() Logger
- func (c *Context) MustGet(key string) any
- func (c *Context) NoContent()
- func (c *Context) NotFound(message string)
- func (c *Context) Param(name string) string
- func (c *Context) Query(name, defaultValue string) string
- func (c *Context) QueryAll(name string) []string
- func (c *Context) Redirect(statusCode int, url string)
- func (c *Context) ResponseWriter() http.ResponseWriter
- func (c *Context) Set(key string, value any)
- func (c *Context) SetHeader(key, value string)
- func (c *Context) Status() int
- func (c *Context) String(statusCode int, text string)
- func (c *Context) Stringf(statusCode int, format string, a ...any)
- func (c *Context) Success(data any)
- func (c *Context) SuccessWithMeta(data, meta any)
- func (c *Context) TooManyRequests()
- func (c *Context) Unauthorized(message string)
- func (c *Context) UnprocessableEntity(message string, details any)
- func (c *Context) Written() bool
- type ErrorDetail
- type HandlerFunc
- type Logger
- type MiddlewareFunc
- type PageMeta
- type Params
- type Response
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetClaims ¶
GetClaims retrieves JWT claims from the request context. Returns nil if no claims have been stored (unauthenticated request).
func Release ¶
func Release(ctx *Context)
Release returns the Context to the pool. Called by the router after the handler chain completes.
Types ¶
type Context ¶
type Context struct {
// Request is the incoming HTTP request. Access headers, body, and query
// parameters directly through this field.
Request *http.Request
// contains filtered or unexported fields
}
Context is the central type passed to every route handler and middleware. It wraps the http.ResponseWriter and *http.Request and adds convenience methods for the most common operations.
A Context is recycled from a sync.Pool to minimise allocation pressure. Do not hold a reference to a Context after the handler returns.
func NewContext ¶
func NewContext(w http.ResponseWriter, r *http.Request) *Context
NewContext allocates (or retrieves from the pool) a Context and initialises it for the current request. Called by the router on every request.
func (*Context) AddHeader ¶
AddHeader adds a response header value without replacing existing values.
func (*Context) BadRequest ¶
BadRequest writes a 400 response.
func (*Context) BindJSON ¶
BindJSON reads the request body, decodes it as JSON into dst, and closes the body. Returns an error if the body is not valid JSON or cannot be decoded into dst.
The request Content-Type does not need to be application/json; this method always attempts JSON decoding regardless.
func (*Context) Blob ¶
Blob writes raw bytes with the specified Content-Type. Useful for serving binary data (images, PDFs, etc.).
func (*Context) BodyBytes ¶
BodyBytes reads and returns the raw request body. The body can only be read once; subsequent calls return an empty byte slice. Prefer BindJSON for JSON payloads.
func (*Context) Claims ¶
Claims returns the JWT claims stored in the request context by the auth middleware. Returns nil for unauthenticated requests.
func (*Context) ClientIP ¶
ClientIP returns the most-accurate client IP address available.
It checks X-Forwarded-For before falling back to RemoteAddr. Crucially, X-Forwarded-For is ONLY trusted if the direct connection (RemoteAddr) originates from a known Cloudflare IP address. This prevents IP spoofing from non-Cloudflare sources.
func (*Context) Conflict ¶
Conflict writes a 409 response. Use for duplicate resource creation attempts.
func (*Context) ContentType ¶
ContentType returns the media type of the request body, stripping parameters (e.g., "application/json" from "application/json; charset=utf-8").
func (*Context) Fail ¶
Fail writes an error response using the standard envelope.
ctx.Fail(http.StatusBadRequest, "VALIDATION_ERROR", "email is required", nil)
func (*Context) Forbidden ¶
Forbidden writes a 403 response. Use this when the caller is authenticated but lacks permission to access the resource.
func (*Context) Get ¶
Get retrieves a value stored by Set. Returns the value and true if found. Thread-safe.
func (*Context) InternalServerError ¶
InternalServerError writes a 500 response. Avoid exposing internal error details to clients in production.
func (*Context) JSON ¶
JSON writes a JSON-encoded body with the given HTTP status code. It sets Content-Type to "application/json; charset=utf-8". Encoding errors are handled gracefully by writing a 500 response.
func (*Context) Logger ¶
Logger returns the logger stored in the request-scoped keys.
If no logger was set (e.g., the Logger middleware is disabled), it returns a no-op logger to prevent nil pointer panics in handlers.
func (*Context) MustGet ¶
MustGet retrieves a value by key and panics if it is not found. Use this only when the value is guaranteed to exist (e.g., set by a required middleware that runs before this handler).
func (*Context) NoContent ¶
func (c *Context) NoContent()
NoContent writes a 204 No Content response. The body is intentionally empty.
func (*Context) Param ¶
Param returns the URL path parameter with the given name. Returns an empty string if the parameter was not captured.
// Route: /users/:id
id := ctx.Param("id")
func (*Context) Query ¶
Query returns the first value of the named query string parameter. Returns the provided default value if the parameter is absent.
page := ctx.Query("page", "1")
func (*Context) Redirect ¶
Redirect sends an HTTP redirect to the given URL. Use 301 (permanent) or 302/307/308 (temporary) as appropriate.
func (*Context) ResponseWriter ¶
func (c *Context) ResponseWriter() http.ResponseWriter
ResponseWriter returns the underlying http.ResponseWriter so that callers can use it with third-party middleware that requires the raw interface.
func (*Context) Set ¶
Set stores a value under the given key. Values survive for the duration of the request and are accessible to all subsequent middleware and handlers. Thread-safe.
func (*Context) SetHeader ¶
SetHeader sets a response header value. Must be called before any body bytes are written.
func (*Context) Stringf ¶ added in v0.5.3
Stringf writes a formatted plain-text response with the given status code.
func (*Context) Success ¶
Success writes a 200 OK response using the standard envelope.
ctx.Success(map[string]string{"status": "created"})
func (*Context) SuccessWithMeta ¶
SuccessWithMeta writes a 200 OK response that includes pagination or other metadata alongside the data payload.
func (*Context) TooManyRequests ¶
func (c *Context) TooManyRequests()
TooManyRequests writes a 429 response. Used by the rate-limit middleware.
func (*Context) Unauthorized ¶
Unauthorized writes a 401 response. Use this when authentication is required but the request provides no valid credentials.
func (*Context) UnprocessableEntity ¶
UnprocessableEntity writes a 422 response with optional field-level details.
ctx.UnprocessableEntity("validation failed", map[string]string{
"email": "must be a valid email address",
"username": "already taken",
})
type ErrorDetail ¶
type ErrorDetail struct {
// Code is a machine-readable error identifier (e.g., "VALIDATION_ERROR").
Code string `json:"code"`
// Message is a human-readable description of the error.
Message string `json:"message"`
// Details holds field-level validation errors or additional context.
// Omitted when nil.
Details any `json:"details,omitempty"`
}
ErrorDetail carries structured error information within a Response.
type HandlerFunc ¶
type HandlerFunc func(ctx *Context)
HandlerFunc is the function signature for all route handlers. Handlers receive a *Context that exposes helpers for every common operation.
type Logger ¶
type Logger interface {
Debug(msg string, kv ...any)
Info(msg string, kv ...any)
Warn(msg string, kv ...any)
Error(msg string, kv ...any)
}
Logger defines the interface for structured logging within a handler. It is compatible with log/slog and the gocore/logger package.
type MiddlewareFunc ¶
type MiddlewareFunc func(next HandlerFunc) HandlerFunc
MiddlewareFunc wraps a HandlerFunc to intercept the request/response cycle. Middleware must call next(ctx) to pass control to the next handler or middleware in the chain.
func MyMiddleware(next handler.HandlerFunc) handler.HandlerFunc {
return func(ctx *handler.Context) {
// before handler
next(ctx)
// after handler
}
}
type PageMeta ¶
type PageMeta struct {
Page int `json:"page"`
PerPage int `json:"per_page"`
TotalItems int64 `json:"total_items"`
TotalPages int `json:"total_pages"`
}
PageMeta holds standard pagination metadata for list endpoints.
type Params ¶
Params holds URL path parameters extracted during route matching. e.g. for route /users/:id — Params{"id": "42"}.
type Response ¶
type Response struct {
// Success indicates whether the request was handled without error.
Success bool `json:"success"`
// Data holds the response payload for successful requests.
// Omitted when nil (error responses).
Data any `json:"data,omitempty"`
// Error holds error details for failed requests.
// Omitted when nil (success responses).
Error *ErrorDetail `json:"error,omitempty"`
// Meta holds optional pagination or request metadata.
// Omitted when nil.
Meta any `json:"meta,omitempty"`
}
Response is the standard JSON envelope returned by all API endpoints. Using a consistent shape simplifies client-side parsing and logging.
{
"success": true,
"data": { ... }
}
{
"success": false,
"error": { "code": "NOT_FOUND", "message": "resource not found" }
}