RespKit

Architecture

Core contracts

  • resp.OK, resp.Created, resp.NoContent, resp.Fail, and resp.NotFound work without registration or setup.
  • The default envelope uses snake_case for RespKit-owned keys. Application data keeps its original keys.
  • Custom naming, extra language catalogs, error mappers, Problem Details, and debug messages are opt-in.
  • Raw internal error messages stay out of ordinary response bodies. WithExposeInternalErrors(true) is unsafe for public services.
  • The core module does not import Gin, Echo, Fiber, or other HTTP frameworks. net/http, Chi, Gorilla/mux, and Beego v2 use resp.HTTP(w, r).
  • The core module supports Go 1.22 and later and depends only on the standard library.

Package boundaries

Application handler

resp
Public API and engine

Internal packages

  • Transport
  • Error resolver
  • Localization
  • Response formatter
  • Diagnostics

Applications call resp, which depends on the internal packages.

PackageResponsibility
respPublic helpers, configuration, and the response engine.
internal/transportDetect framework contexts and write HTTP responses.
internal/resolverMap typed errors to public codes and HTTP statuses.
internal/i18nSelect locales and look up translated messages.
internal/formatterBuild envelopes, apply key naming, and format Problem Details.
internal/diagnosticsDescribe error classifications for inspection and the CLI.

Applications and integrations use the exported API in resp. Packages under internal/ are implementation details. They may import the standard library, but they do not import resp, which keeps dependencies flowing in one direction.

Response flow

  1. A package-level helper or an immutable Engine receives the response request.
  2. The resolver classifies errors with errors.Is and errors.As. Unknown errors receive status 500 and a generic public message.
  3. Transport selects a framework adapter using its supported interfaces. Reflection is limited to framework methods with incompatible signatures.
  4. The request's Accept-Language header or a response option selects a translation catalog. Public error codes remain the same across locales.
  5. The formatter creates an envelope or RFC 9457 error body without changing application data keys.
  6. RespKit encodes the JSON before writing the status. Responses to HEAD requests and status 204 have no body.
  7. CLI diagnostics expose classification metadata without printing raw application error messages.

Source layout

resp/                  Public API, engine, helpers, and facade
internal/transport/    Framework adapters and context detection
internal/resolver/     Error classification and SQLSTATE mapping
internal/i18n/         Embedded JSON catalogs and language matching
internal/formatter/    Envelopes, naming options, and Problem Details
internal/diagnostics/  Error metadata for CLI consumers
cmd/respkit/           doctor, catalog, explain, and version commands
examples/nethttp/      Runnable net/http example
integrations/          Framework tests and optional adapters
book/                  Documentation source and static website

Contribution guidelines

  • Add framework support under internal/transport/; do not import frameworks from the resp package.
  • Store built-in translations as separate JSON files under internal/i18n/locales/.
  • Add error mappings only when their meaning is deterministic and safe. Use a separate optional module for dependency-specific errors.
  • Cover wrapped errors, invalid input, locale fallback, and error confidentiality in tests.
  • resp.Configure replaces the default engine atomically. Do not mutate an existing engine's maps or slices.
  • Pin framework versions in the integration module and test against the upstream routers.

Known limits

  • Framework runtime tests live in integrations/framework-tests; production adapters live in separate optional modules.
  • Fiber's Status(int) call uses reflection because Fiber v2 and v3 return different types from that method.
  • A framework context is request-scoped, and a response can be written only once. RespKit cannot change a status after it has been sent.
  • The 100% gate measures combined statement coverage for resp and internal/.... It does not imply full branch coverage or test every dependency version.

On this page