Skip to content

Commit fbc8e0d

Browse files
mromaszewiczclaude
andauthored
revert external-ref carve-out in strict-server response embedding (#2010) (#2357)
PR #1387 added an `$isExternalRef` branch to the strict-{,fiber-,iris-} interface templates that strips the `<NameTag>Response` suffix when embedding an external response ref. That made external refs to a `components/responses/...` resolve to the bare schema name (`N400`) instead of the strict envelope (`N400JSONResponse`). The result: when spec A and spec B both generate strict-server and A $refs B's response component, A's local envelope embeds `N400JSONResponse` while A's external-ref envelope embeds `externalRef0.N400`. The two struct shapes are no longer identical, so cross-package response casts (the standard pattern for sharing error shapes across services) stop compiling — the regression filed as #2010. Investigation showed there is no smarter alternative: non-strict server modes emit no top-level type for `components/responses/...`, only `models: true` (gives the bare alias) and `strict-server: true` (gives the `<Name>JSONResponse` envelope, which is also the only form that carries a `Headers` field in the with-headers case) do. Changes: - Drop the `$isExternalRef` carve-out from the three strict-interface templates so external refs use the same `<Name>JSONResponse` embedding as internal refs. - Update `internal/test/issues/issue-removed-external-ref` golden output to match. - Update `internal/test/issues/issue-2113`'s common-package config to also generate `strict-server: true`. The fixture was relying on the PR #1387 behavior; under the new policy the destination of a strict-server external ref must also generate a strict server, so `StandardErrorJSONResponse` is in scope. - Add `internal/test/issues/issue-2010` regression fixture: two specs with strict-server, the second `$ref`s the first's `components/responses/400`, and the test exercises the cross-package cast that was broken. - README: note the cross-spec strict-server requirement under the strict-server section. The earlier two commits of #1387 are kept: the `Schema.IsExternalRef` helper, and the alias-vs-defined-type fix for content-schema external refs (which is a genuinely independent bug fix — methods can't be attached to non-local aliases). BREAKING CHANGE: external `$ref` to a `components/responses/...` from a strict-server target now requires the destination spec to also generate `strict-server: true`. This restores cross-package response casting that worked in v2.0.0 and earlier. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7517e09 commit fbc8e0d

18 files changed

Lines changed: 645 additions & 8 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,6 +1534,9 @@ output: server.gen.go
15341534
> [!NOTE]
15351535
> This doesn't include [validation of incoming requests](#requestresponse-validation-middleware).
15361536
1537+
> [!IMPORTANT]
1538+
> When a strict-server spec uses `$ref` to point at a `components/responses/...` (or `components/requestBodies/...`) defined in another spec via `import-mapping`, the destination spec **must also be generated with `strict-server: true`**. The strict envelope embeds the `<Name>JSONResponse` type from the destination package; that type only exists when the destination generates a strict server. Without it the generated code will fail to compile with an "undefined" error. See [issue #2010](https://github.com/oapi-codegen/oapi-codegen/issues/2010).
1539+
15371540
## Generating API clients
15381541

15391542
As well as generating the server-side boilerplate, `oapi-codegen` can also generate API clients.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
# yaml-language-server: $schema=../../../../configuration-schema.json
3+
package: spec_base
4+
generate:
5+
chi-server: true
6+
strict-server: true
7+
models: true
8+
output: gen/spec_base/issue.gen.go
9+
output-options:
10+
skip-prune: true
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
# yaml-language-server: $schema=../../../../configuration-schema.json
3+
package: spec_other
4+
generate:
5+
chi-server: true
6+
strict-server: true
7+
models: true
8+
import-mapping:
9+
./spec-base.yaml: "github.com/oapi-codegen/oapi-codegen/v2/internal/test/issues/issue-2010/gen/spec_base"
10+
output: gen/spec_other/issue.gen.go
11+
output-options:
12+
skip-prune: true
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// Regression fixture for https://github.com/oapi-codegen/oapi-codegen/issues/2010.
2+
//
3+
// The base spec defines components/responses/400 with a JSON body. The "other"
4+
// spec references that response via an external $ref. With strict-server
5+
// enabled in both packages, the embedded response field name must agree across
6+
// packages so cross-package response casts compile.
7+
package issue_2010
8+
9+
//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.base.yaml spec-base.yaml
10+
//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen --config=config.other.yaml spec-other.yaml

internal/test/issues/issue-2010/gen/spec_base/.gitempty

Whitespace-only changes.

internal/test/issues/issue-2010/gen/spec_base/issue.gen.go

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

internal/test/issues/issue-2010/gen/spec_other/.gitempty

Whitespace-only changes.

0 commit comments

Comments
 (0)