handler

package
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 11 Imported by: 0

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

Constants

This section is empty.

Variables

This section is empty.

Functions

func GetClaims

func GetClaims(r *http.Request) *auth.Claims

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.

func SetClaims

func SetClaims(r *http.Request, c *auth.Claims) *http.Request

SetClaims stores JWT claims in the request context. Called by the auth middleware after successful token validation.

func SetParams

func SetParams(r *http.Request, p Params) *http.Request

SetParams stores URL parameters in a request's context and returns the updated *http.Request. Called by the router after a successful match.

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

func (c *Context) AddHeader(key, value string)

AddHeader adds a response header value without replacing existing values.

func (*Context) BadRequest

func (c *Context) BadRequest(message string)

BadRequest writes a 400 response.

func (*Context) BindJSON

func (c *Context) BindJSON(dst any) error

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

func (c *Context) Blob(statusCode int, contentType string, data []byte)

Blob writes raw bytes with the specified Content-Type. Useful for serving binary data (images, PDFs, etc.).

func (*Context) BodyBytes

func (c *Context) BodyBytes() ([]byte, error)

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

func (c *Context) Claims() *auth.Claims

Claims returns the JWT claims stored in the request context by the auth middleware. Returns nil for unauthenticated requests.

func (*Context) ClientIP

func (c *Context) ClientIP() string

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

func (c *Context) Conflict(message string)

Conflict writes a 409 response. Use for duplicate resource creation attempts.

func (*Context) ContentType

func (c *Context) ContentType() string

ContentType returns the media type of the request body, stripping parameters (e.g., "application/json" from "application/json; charset=utf-8").

func (*Context) Created

func (c *Context) Created(data any)

Created writes a 201 Created response using the standard envelope.

func (*Context) Fail

func (c *Context) Fail(statusCode int, code, message string, details any)

Fail writes an error response using the standard envelope.

ctx.Fail(http.StatusBadRequest, "VALIDATION_ERROR", "email is required", nil)

func (*Context) Forbidden

func (c *Context) Forbidden(message string)

Forbidden writes a 403 response. Use this when the caller is authenticated but lacks permission to access the resource.

func (*Context) Get

func (c *Context) Get(key string) (any, bool)

Get retrieves a value stored by Set. Returns the value and true if found. Thread-safe.

func (*Context) HTML

func (c *Context) HTML(statusCode int, body string)

HTML writes an HTML response with the given status code.

func (*Context) Header

func (c *Context) Header(name string) string

Header returns the value of the named request header.

func (*Context) InternalServerError

func (c *Context) InternalServerError(message string)

InternalServerError writes a 500 response. Avoid exposing internal error details to clients in production.

func (*Context) JSON

func (c *Context) JSON(statusCode int, v any)

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

func (c *Context) Logger() 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

func (c *Context) MustGet(key string) any

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) NotFound

func (c *Context) NotFound(message string)

NotFound writes a 404 response.

func (*Context) Param

func (c *Context) Param(name string) string

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

func (c *Context) Query(name, defaultValue string) string

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) QueryAll

func (c *Context) QueryAll(name string) []string

QueryAll returns all values for the named query string parameter.

func (*Context) Redirect

func (c *Context) Redirect(statusCode int, url string)

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

func (c *Context) Set(key string, value any)

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

func (c *Context) SetHeader(key, value string)

SetHeader sets a response header value. Must be called before any body bytes are written.

func (*Context) Status

func (c *Context) Status() int

Status returns the HTTP status code written so far (default 200).

func (*Context) String

func (c *Context) String(statusCode int, text string)

String writes a plain-text response with the given status code.

func (*Context) Stringf added in v0.5.3

func (c *Context) Stringf(statusCode int, format string, a ...any)

Stringf writes a formatted plain-text response with the given status code.

func (*Context) Success

func (c *Context) Success(data any)

Success writes a 200 OK response using the standard envelope.

ctx.Success(map[string]string{"status": "created"})

func (*Context) SuccessWithMeta

func (c *Context) SuccessWithMeta(data, meta any)

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

func (c *Context) Unauthorized(message string)

Unauthorized writes a 401 response. Use this when authentication is required but the request provides no valid credentials.

func (*Context) UnprocessableEntity

func (c *Context) UnprocessableEntity(message string, details any)

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",
})

func (*Context) Written

func (c *Context) Written() bool

Written reports whether the response headers have been committed.

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

type Params map[string]string

Params holds URL path parameters extracted during route matching. e.g. for route /users/:id — Params{"id": "42"}.

func GetParams

func GetParams(r *http.Request) Params

GetParams retrieves URL parameters from the request context. Returns an empty (non-nil) Params if none are stored.

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" }
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL