Clients need a description of your HTTP API without having to discover its behavior through requests. Add an operation, the description of one HTTP method and path, beside a route registration. The router exports those descriptions as an OpenAPI document without running your handlers.
An annotation describes behavior; it does not implement it. Your handler still decodes input, applies validation and authorization, and writes its response. Exporting the document and serving documentation are separate tasks.
Describe Output
For a greeting endpoint, use a named response type so the description can follow
the JSON shape your handler writes. These examples use net/http,
arkoren.dev/core/http/response, arkoren.dev/core/http/router, and
arkoren.dev/foundation/validate:
type Greeting struct {
Message string `json:"message"`
}
The handler returns that type through the ordinary response helper:
func greet(writer http.ResponseWriter, incoming *http.Request) error {
return response.JSON(writer, http.StatusOK, Greeting{Message: "Hello"})
}
Register it with an operation callback on your existing routes router:
routes.Get("/greeting", greet, func(operation *router.OperationBuilder) {
operation.Summary("Read a greeting")
operation.JSONResponse(http.StatusOK, validate.Infer[Greeting]())
})
The operation describes a 200 response with application/json content.
validate.Infer[Greeting]() supplies the output type’s JSON Schema; it neither
checks response values nor adds runtime validation. Use
request schemas when the endpoint also accepts
validated input.
Export JSON
After registering your API routes, generate the document:
document, err := routes.OpenAPI("Greeting API", "1.0.0")
On success, document contains deterministic OpenAPI 3.2.1 JSON, including
GET /greeting and its declared response. The supplied 1.0.0 is your API’s
version, not the OpenAPI specification version. No listener, application startup,
request, or browser UI is required.
Check err before saving or distributing the bytes. Generation checks the
supported document structure and declarations; it does not compare them with
handler behavior. The serving guide explains export
failures and live document caching.
The focused fragments in this group retain error results but omit routine error propagation. Complete implementations must handle those errors before using their results.
Contract Boundaries
Only annotated, nonhidden registrations appear in OpenAPI. Routes without an operation callback still work but are omitted; an annotation without responses does not acquire a guessed success response. Grouped routes use their final prefixed paths.
Operation callbacks run synchronously once during registration, in order on the same draft. Schema bytes and examples are captured when supplied, and published metadata is detached from retained drafts. Nil callbacks panic. Finish route registration before exporting concurrently or serving requests.
Annotations do not parse bodies, set headers or statuses, discover middleware errors, or enforce security declarations. Keep them aligned with request validation, response writing, and error mapping. Describing Operations covers their declaration limits.
The exporter does not inspect opaque mounted protocols or infer every integration’s contract. Use the built-in handler guide to choose shipped annotations or describe an integration manually. For broker messages rather than HTTP operations, use AsyncAPI; it produces a separate document, not input for Swagger UI.
For declarations and export methods, see the
router API reference.