Documentation
¶
Overview ¶
Package httpx provides stable core HTTP response and error helpers.
Start with WriteJSON, WriteProblem, WriteErrorWithOptions, ProblemCatalog, TypeRegistry, and HeaderLimits when building JSON APIs that need consistent RFC 9457 Problem Details, bounded header checks, and safe error mapping. The package does not own routing, authentication, persistence, or logging.
ProblemFromErrorWithOptions and WriteErrorWithOptions redact unexpected server errors by default; use strict options when internal details must stay out of client responses. For request identity and panic recovery helpers, use the httpx/identity and httpx/recover subpackages.
Index ¶
- Constants
- Variables
- func DefaultTypeForStatus(status int) string
- func DefaultTypeURI(slug string) string
- func HeaderBytes(h http.Header) int
- func HeaderCount(h http.Header) int
- func TypeURI(base, slug string) string
- func WriteError(w http.ResponseWriter, err error)
- func WriteErrorStrict(w http.ResponseWriter, err error)
- func WriteErrorWithOptions(w http.ResponseWriter, err error, opts ErrorOptions)
- func WriteJSON(w http.ResponseWriter, status int, v any)
- func WriteProblem(w http.ResponseWriter, status int, p Problem)
- func WriteProblemCode(w http.ResponseWriter, code ProblemCode)
- func WriteProblemWithFieldErrors(w http.ResponseWriter, status int, p Problem, errs fielderrors.FieldErrors)
- func WriteSimpleProblem(w http.ResponseWriter, status int, title, detail string)
- type ErrorMode
- type ErrorOptions
- type HTTPError
- type HeaderLimits
- type Problem
- func ProblemFromCode(code ProblemCode) (Problem, int)
- func ProblemFromError(err error) (Problem, int)
- func ProblemFromErrorStrict(err error) (Problem, int)
- func ProblemFromErrorWithCatalog(err error, catalog *ProblemCatalog, opts ErrorOptions) (Problem, int)
- func ProblemFromErrorWithOptions(err error, opts ErrorOptions) (Problem, int)
- func WithFieldErrors(p Problem, errs fielderrors.FieldErrors) Problem
- func WithValidationErrors(p Problem, errs fielderrors.FieldErrors) Problem
- type ProblemCatalog
- type ProblemCode
- type ProblemDefinition
- type ProblemError
- type TypeRegistry
- type ValidationErrors
Examples ¶
Constants ¶
const ( TypeBadRequest = "bad-request" TypeNotAcceptable = "not-acceptable" TypeValidation = "validation-error" TypeUnsupportedMedia = "unsupported-media-type" TypeForbidden = "forbidden" TypeNotFound = "not-found" TypeConflict = "conflict" TypePayloadTooLarge = "payload-too-large" TypeRateLimited = "rate-limit-exceeded" TypeInternal = "internal-error" )
Standard problem type slugs.
const DefaultTypeBase = "https://api-toolkit.dev/problems"
DefaultTypeBase is the canonical base URI for toolkit problem types.
const ValidationErrorsKey = "validation"
ValidationErrorsKey is the canonical extension key for field errors.
Variables ¶
var ( ErrForbidden = errors.New("forbidden") ErrTooManyRequests = errors.New("rate limit exceeded") )
Sentinel errors for common HTTP categories.
var ( ErrHeaderBytesExceeded = errors.New("request headers exceed max bytes") ErrHeaderCountExceeded = errors.New("request headers exceed max count") )
var ( HeaderLimitsStrict = HeaderLimits{MaxBytes: 32 << 10, MaxCount: 40} HeaderLimitsBalanced = HeaderLimits{MaxBytes: 64 << 10, MaxCount: 100} HeaderLimitsRelaxed = HeaderLimits{MaxBytes: 1 << 20, MaxCount: 200} )
Functions ¶
func DefaultTypeForStatus ¶
DefaultTypeForStatus returns the standard type URI for a status code.
func DefaultTypeURI ¶
DefaultTypeURI resolves a standard type slug to a full URI.
func HeaderBytes ¶
HeaderBytes returns an approximate size for header names and values.
func HeaderCount ¶
HeaderCount returns the total number of header values.
func WriteError ¶
func WriteError(w http.ResponseWriter, err error)
WriteError maps an error to a Problem Details response.
func WriteErrorStrict ¶
func WriteErrorStrict(w http.ResponseWriter, err error)
WriteErrorStrict maps an error to a Problem Details response with redaction.
func WriteErrorWithOptions ¶
func WriteErrorWithOptions(w http.ResponseWriter, err error, opts ErrorOptions)
WriteErrorWithOptions maps an error to Problem Details using custom options.
func WriteJSON ¶
func WriteJSON(w http.ResponseWriter, status int, v any)
WriteJSON writes a JSON response with a buffered marshal to avoid partial writes.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"github.com/aatuh/api-toolkit/v3/httpx"
)
func main() {
rec := httptest.NewRecorder()
httpx.WriteJSON(rec, http.StatusAccepted, map[string]string{"status": "ok"})
fmt.Println(rec.Code)
fmt.Println(strings.TrimSpace(rec.Body.String()))
}
Output: 202 {"status":"ok"}
func WriteProblem ¶
func WriteProblem(w http.ResponseWriter, status int, p Problem)
WriteProblem writes a problem details response with the provided status code. It merges extension fields after the standard members, per RFC 9457.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"github.com/aatuh/api-toolkit/v3/httpx"
)
func main() {
rec := httptest.NewRecorder()
httpx.WriteProblem(rec, http.StatusBadRequest, httpx.Problem{
Type: httpx.DefaultTypeURI(httpx.TypeValidation),
Title: http.StatusText(http.StatusBadRequest),
Detail: "validation failed",
})
fmt.Println(rec.Code)
fmt.Println(rec.Header().Get("Content-Type"))
}
Output: 400 application/problem+json
func WriteProblemCode ¶
func WriteProblemCode(w http.ResponseWriter, code ProblemCode)
WriteProblemCode writes a Problem Details response for a code.
func WriteProblemWithFieldErrors ¶
func WriteProblemWithFieldErrors(w http.ResponseWriter, status int, p Problem, errs fielderrors.FieldErrors)
WriteProblemWithFieldErrors writes problem details with field errors attached.
func WriteSimpleProblem ¶
func WriteSimpleProblem(w http.ResponseWriter, status int, title, detail string)
WriteSimpleProblem is a convenience for common cases.
Types ¶
type ErrorOptions ¶
type ErrorOptions struct {
Mode ErrorMode
TypeRegistry *TypeRegistry
}
ErrorOptions customizes how errors are mapped to problems.
type HTTPError ¶
HTTPError carries an explicit HTTP status and response detail.
func NewHTTPError ¶
NewHTTPError constructs an HTTPError with status and detail.
type HeaderLimits ¶
type HeaderLimits struct {
// MaxBytes caps the approximate header bytes (name + value + separators).
MaxBytes int
// MaxCount caps the total number of header values.
MaxCount int
}
HeaderLimits defines request header size/count limits.
func (HeaderLimits) ApplyServer ¶
func (l HeaderLimits) ApplyServer(s *http.Server)
ApplyServer sets MaxHeaderBytes using the configured limit.
type Problem ¶
type Problem struct {
Type string `json:"type,omitempty"` // "https://example.com/validation-error"`
Title string `json:"title,omitempty"` // "Bad Request"`
Status int `json:"status,omitempty"` // 400
Detail string `json:"detail,omitempty"` // "name is required"
Instance string `json:"instance,omitempty"` // "/api/v1/foo/123"
Ext map[string]any `json:"-"`
}
Problem represents an RFC 9457 problem details response body. RFC 9457 obsoletes RFC 7807. See: https://www.rfc-editor.org/rfc/rfc9457.html
func ProblemFromCode ¶
func ProblemFromCode(code ProblemCode) (Problem, int)
ProblemFromCode maps a code to Problem Details with the default catalog.
func ProblemFromError ¶
ProblemFromError maps errors to a Problem and HTTP status code.
func ProblemFromErrorStrict ¶
ProblemFromErrorStrict redacts 5xx details to avoid internal leakage.
func ProblemFromErrorWithCatalog ¶
func ProblemFromErrorWithCatalog(err error, catalog *ProblemCatalog, opts ErrorOptions) (Problem, int)
ProblemFromErrorWithCatalog maps errors to Problem Details using a catalog.
func ProblemFromErrorWithOptions ¶
func ProblemFromErrorWithOptions(err error, opts ErrorOptions) (Problem, int)
ProblemFromErrorWithOptions maps errors to a Problem using custom options.
func WithFieldErrors ¶
func WithFieldErrors(p Problem, errs fielderrors.FieldErrors) Problem
WithFieldErrors attaches field-level errors to a problem payload.
func WithValidationErrors ¶
func WithValidationErrors(p Problem, errs fielderrors.FieldErrors) Problem
WithValidationErrors attaches canonical validation errors to a problem payload.
type ProblemCatalog ¶
type ProblemCatalog struct {
// contains filtered or unexported fields
}
ProblemCatalog maps stable codes to Problem Details definitions.
func DefaultProblemCatalog ¶
func DefaultProblemCatalog() *ProblemCatalog
DefaultProblemCatalog returns the toolkit default problem catalog.
func NewProblemCatalog ¶
func NewProblemCatalog(definitions ...ProblemDefinition) *ProblemCatalog
NewProblemCatalog constructs a catalog from definitions.
func (*ProblemCatalog) Definition ¶
func (c *ProblemCatalog) Definition(code ProblemCode) (ProblemDefinition, bool)
Definition returns a problem definition by code.
func (*ProblemCatalog) Definitions ¶
func (catalog *ProblemCatalog) Definitions() []ProblemDefinition
Definitions returns all problem definitions in deterministic code order.
func (*ProblemCatalog) Problem ¶
func (c *ProblemCatalog) Problem(code ProblemCode, detail string) (Problem, int)
Problem maps a code to Problem Details.
func (*ProblemCatalog) Register ¶
func (c *ProblemCatalog) Register(definition ProblemDefinition)
Register adds or replaces a problem definition.
type ProblemDefinition ¶
type ProblemDefinition struct {
Code ProblemCode
Status int
Type string
Title string
Detail string
Retryable bool
DocumentationURL string
LogLevel string
}
ProblemDefinition describes one problem code.
type ProblemError ¶
type ProblemError struct {
Code ProblemCode
Detail string
Err error
}
ProblemError carries a problem code and optional underlying error.
func NewProblemError ¶
func NewProblemError(code ProblemCode, detail string, err error) *ProblemError
NewProblemError constructs a coded problem error.
func (*ProblemError) Error ¶
func (e *ProblemError) Error() string
func (*ProblemError) Unwrap ¶
func (e *ProblemError) Unwrap() error
type TypeRegistry ¶
type TypeRegistry struct {
// contains filtered or unexported fields
}
TypeRegistry helps build consistent problem type URIs.
func DefaultTypeRegistry ¶
func DefaultTypeRegistry() *TypeRegistry
DefaultTypeRegistry returns a registry with the toolkit's standard type slugs.
func NewTypeRegistry ¶
func NewTypeRegistry(base string, slugs ...string) *TypeRegistry
NewTypeRegistry registers slugs against a base URI.
func (*TypeRegistry) Register ¶
func (r *TypeRegistry) Register(slug string) string
Register adds a slug to the registry and returns its URI.
func (*TypeRegistry) Types ¶
func (r *TypeRegistry) Types() map[string]string
Types returns a copy of the registered type map.
func (*TypeRegistry) URI ¶
func (r *TypeRegistry) URI(slug string) string
URI returns the full URI for a slug, falling back to base + slug.
type ValidationErrors ¶
type ValidationErrors struct {
Fields fielderrors.FieldErrors `json:"fields,omitempty"`
}
ValidationErrors wraps field-level validation errors for Problem extensions.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package identity resolves canonical request identity values.
|
Package identity resolves canonical request identity values. |
|
Package recover provides panic recovery utilities for HTTP handlers.
|
Package recover provides panic recovery utilities for HTTP handlers. |