httpx

package
v2.1.0 Latest Latest
Warning

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

Go to latest
Published: May 2, 2026 License: Apache-2.0 Imports: 6 Imported by: 12

Documentation

Overview

Package httpx provides HTTP utilities, including RFC 9457 Problem Details helpers.

Index

Examples

Constants

View Source
const (
	TypeBadRequest         = "bad-request"
	TypeNotAcceptable      = "not-acceptable"
	TypeValidation         = "validation-error"
	TypeUnsupportedMedia   = "unsupported-media-type"
	TypeUnauthorized       = "unauthorized"
	TypeForbidden          = "forbidden"
	TypeNotFound           = "not-found"
	TypeConflict           = "conflict"
	TypePayloadTooLarge    = "payload-too-large"
	TypeRateLimited        = "rate-limit-exceeded"
	TypeServiceUnavailable = "service-unavailable"
	TypeInternal           = "internal-error"
)

Standard problem type slugs.

View Source
const DefaultTypeBase = "https://api-toolkit.dev/problems"

DefaultTypeBase is the canonical base URI for toolkit problem types.

View Source
const ValidationErrorsKey = "validation"

ValidationErrorsKey is the canonical extension key for field errors.

Variables

View Source
var (
	ErrUnauthorized    = errors.New("unauthorized")
	ErrForbidden       = errors.New("forbidden")
	ErrTooManyRequests = errors.New("rate limit exceeded")
)

Sentinel errors for common HTTP categories.

View Source
var (
	ErrHeaderBytesExceeded = errors.New("request headers exceed max bytes")
	ErrHeaderCountExceeded = errors.New("request headers exceed max count")
)
View Source
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

func DefaultTypeForStatus(status int) string

DefaultTypeForStatus returns the standard type URI for a status code.

func DefaultTypeURI

func DefaultTypeURI(slug string) string

DefaultTypeURI resolves a standard type slug to a full URI.

func HeaderBytes

func HeaderBytes(h http.Header) int

HeaderBytes returns an approximate size for header names and values.

func HeaderCount

func HeaderCount(h http.Header) int

HeaderCount returns the total number of header values.

func TypeURI

func TypeURI(base, slug string) string

TypeURI builds a type URI from base and slug.

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/v2/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/v2/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 added in v2.1.0

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 ErrorMode

type ErrorMode int

ErrorMode controls how problems are produced from errors.

const (
	// ErrorModeDefault preserves details for non-internal errors.
	ErrorModeDefault ErrorMode = iota
	// ErrorModeStrict redacts details for 5xx responses.
	ErrorModeStrict
)

type ErrorOptions

type ErrorOptions struct {
	Mode         ErrorMode
	TypeRegistry *TypeRegistry
}

ErrorOptions customizes how errors are mapped to problems.

type HTTPError

type HTTPError struct {
	Status int
	Title  string
	Detail string
	Type   string
	Err    error
}

HTTPError carries an explicit HTTP status and response detail.

func NewHTTPError

func NewHTTPError(status int, detail string) *HTTPError

NewHTTPError constructs an HTTPError with status and detail.

func (*HTTPError) Error

func (e *HTTPError) Error() string

func (*HTTPError) Unwrap

func (e *HTTPError) Unwrap() error

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.

func (HeaderLimits) Check

func (l HeaderLimits) Check(r *http.Request) error

Check validates the request headers against configured limits.

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 added in v2.1.0

func ProblemFromCode(code ProblemCode) (Problem, int)

ProblemFromCode maps a code to Problem Details with the default catalog.

func ProblemFromError

func ProblemFromError(err error) (Problem, int)

ProblemFromError maps errors to a Problem and HTTP status code.

func ProblemFromErrorStrict

func ProblemFromErrorStrict(err error) (Problem, int)

ProblemFromErrorStrict redacts 5xx details to avoid internal leakage.

func ProblemFromErrorWithCatalog added in v2.1.0

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.

func (*Problem) With

func (p *Problem) With(key string, value any) *Problem

With adds an extension field to the problem payload.

type ProblemCatalog added in v2.1.0

type ProblemCatalog struct {
	// contains filtered or unexported fields
}

ProblemCatalog maps stable codes to Problem Details definitions.

func DefaultProblemCatalog added in v2.1.0

func DefaultProblemCatalog() *ProblemCatalog

DefaultProblemCatalog returns the toolkit default problem catalog.

func NewProblemCatalog added in v2.1.0

func NewProblemCatalog(definitions ...ProblemDefinition) *ProblemCatalog

NewProblemCatalog constructs a catalog from definitions.

func (*ProblemCatalog) Definition added in v2.1.0

func (c *ProblemCatalog) Definition(code ProblemCode) (ProblemDefinition, bool)

Definition returns a problem definition by code.

func (*ProblemCatalog) Problem added in v2.1.0

func (c *ProblemCatalog) Problem(code ProblemCode, detail string) (Problem, int)

Problem maps a code to Problem Details.

func (*ProblemCatalog) Register added in v2.1.0

func (c *ProblemCatalog) Register(definition ProblemDefinition)

Register adds or replaces a problem definition.

type ProblemCode added in v2.1.0

type ProblemCode string

ProblemCode is a stable machine-readable problem code.

type ProblemDefinition added in v2.1.0

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 added in v2.1.0

type ProblemError struct {
	Code   ProblemCode
	Detail string
	Err    error
}

ProblemError carries a problem code and optional underlying error.

func NewProblemError added in v2.1.0

func NewProblemError(code ProblemCode, detail string, err error) *ProblemError

NewProblemError constructs a coded problem error.

func (*ProblemError) Error added in v2.1.0

func (e *ProblemError) Error() string

func (*ProblemError) Unwrap added in v2.1.0

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.

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.

Jump to

Keyboard shortcuts

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