Architecture
Core contracts
resp.OK,resp.Created,resp.NoContent,resp.Fail, andresp.NotFoundwork without registration or setup.- The default envelope uses
snake_casefor 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 useresp.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.
| Package | Responsibility |
|---|---|
resp | Public helpers, configuration, and the response engine. |
internal/transport | Detect framework contexts and write HTTP responses. |
internal/resolver | Map typed errors to public codes and HTTP statuses. |
internal/i18n | Select locales and look up translated messages. |
internal/formatter | Build envelopes, apply key naming, and format Problem Details. |
internal/diagnostics | Describe 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
- A package-level helper or an immutable
Enginereceives the response request. - The resolver classifies errors with
errors.Isanderrors.As. Unknown errors receive status 500 and a generic public message. - Transport selects a framework adapter using its supported interfaces. Reflection is limited to framework methods with incompatible signatures.
- The request's
Accept-Languageheader or a response option selects a translation catalog. Public error codes remain the same across locales. - The formatter creates an envelope or RFC 9457 error body without changing application data keys.
- RespKit encodes the JSON before writing the status. Responses to
HEADrequests and status 204 have no body. - 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 websiteContribution guidelines
- Add framework support under
internal/transport/; do not import frameworks from theresppackage. - 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.Configurereplaces 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
respandinternal/.... It does not imply full branch coverage or test every dependency version.
