Skip to content

Commit 9efd95a

Browse files
mromaszewiczclaude
andauthored
Parse declared response headers into typed fields on client response wrappers (oapi-codegen#2462)
Closes: oapi-codegen#2011 Response headers declared in the spec were dropped by the generated client: the response wrapper exposed only the body fields, leaving declared headers reachable solely through the raw http.Response. The strict server already generates typed header structs and writes them in its Visit* methods; the client had no equivalent on the read side. Each response that declares headers now generates a client-local struct named after the response wrapper (e.g. GetFooResponse200Headers), and the wrapper gains a matching Headers<StatusCode> pointer field (Headers200, HeadersDefault, ...) populated by Parse<Op>Response using runtime.BindStyledParameterWithOptions with ParamLocationHeader ("simple" style, per the OpenAPI spec for response headers). Deriving the type name from the wrapper (via genResponseTypeName) keeps it collision-resolver-aware, and the types are emitted and consumed entirely within the client output, independent of the strict server's <Op><Status>ResponseHeaders types. Binding is lenient: an absent header - even a required one - leaves the field at its zero value rather than failing the parse, mirroring the body unmarshal's tolerance of spec-violating servers; a present header that fails to bind to its declared type is an error. Case clauses are ordered most-specific-first (exact codes, then range wildcards, then default) by the same lexicographic scheme the body unmarshal uses. The change is purely additive: specs without response headers generate byte-identical output, and no strict-server or model output changes. Co-authored-by: Claude Fable 5 <[email protected]>
1 parent 28e0964 commit 9efd95a

12 files changed

Lines changed: 840 additions & 0 deletions

File tree

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# yaml-language-server: $schema=../../../../configuration-schema.json
2+
# From issue-2011
3+
package: responseheaders
4+
output: headers.gen.go
5+
generate:
6+
models: true
7+
client: true
8+
output-options:
9+
# Exercises the nullable.Nullable[T] header-binding path (IsNullable).
10+
nullable-type: true
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Package responseheaders verifies that response headers declared in the
2+
// spec are parsed into typed Headers<StatusCode> fields on the generated
3+
// client response wrappers. The header structs are client-local types named
4+
// after the response wrapper (e.g. GetFooResponse200Headers), emitted and
5+
// consumed entirely within the client output; specs without response
6+
// headers generate no additional code.
7+
//
8+
// From issue-2011.
9+
package responseheaders
10+
11+
//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.yaml spec.yaml

internal/test/clients/responseheaders/headers.gen.go

Lines changed: 355 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)