Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2487,6 +2487,17 @@ Explicitly order struct fields
<tr>
<td>

`x-go-embedding`

</td>
<td>
Embed referenced schema(s) into the generated struct when using `allOf`
</td>
</tr>

<tr>
<td>

`x-oapi-codegen-only-honour-go-name`

</td>
Expand Down Expand Up @@ -3154,6 +3165,53 @@ type ClientWithExtension struct {

You can see this in more detail in [the example code](examples/extensions/xorder/).

### `x-go-embedding` - embed referenced schema(s) into the generated struct when using `allOf`

When composing schemas with `allOf`, setting `x-go-embedding: true` on the composed type causes referenced schema(s) to be embedded in the generated Go struct. This results in Go field promotion for the embedded type(s).

We can see this at play with the following schemas:

```yaml
openapi: "3.0.1"
info:
version: 1.0.0
title: x-go-embedding
components:
schemas:
response.Placeholder:
x-go-embedding: true
type: object
allOf:
- $ref: "#/components/schemas/Response"
- type: object
properties:
hello:
type: string

Response:
x-go-name: Response
type: object
properties:
status:
type: integer
```

This will produce models similar to:

```go
// Response defines model for Response.
type Response struct {
Status *int `json:"status,omitempty"`
}

// ResponsePlaceholder defines model for response.Placeholder.
// Note the embedded Response, due to x-go-embedding: true
type ResponsePlaceholder struct {
Response
Hello *string `json:"hello,omitempty"`
}
```

### `x-oapi-codegen-only-honour-go-name` - only honour the `x-go-name` when generating field names


Expand Down
5 changes: 5 additions & 0 deletions internal/test/x-go/x-go-embedding/all_of/cfg.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# yaml-language-server: $schema=../../configuration-schema.json
package: x_go_embedding_all_of
output: x_go_embedding_all_of.gen.go
generate:
models: true
3 changes: 3 additions & 0 deletions internal/test/x-go/x-go-embedding/all_of/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package x_go_embedding_all_of

//go:generate go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen -config cfg.yaml openapi.yaml
33 changes: 33 additions & 0 deletions internal/test/x-go/x-go-embedding/all_of/openapi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
openapi: "3.0.1"
info:
version: 1.0.0
title: Tests x-go-embeding AllOf composition
paths:
/placeholder:
get:
operationId: placeholder
responses:
default:
description: placeholder
content:
application/json:
schema:
$ref: "#/components/schemas/response.Placeholder"
components:
schemas:
response.Placeholder:
x-go-embedding: true
type: object
allOf:
- $ref: "#/components/schemas/Response"
- type: object
properties:
hello:
type: string

Response:
x-go-name: Response
type: object
properties:
status:
type: integer

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pkg/codegen/extension.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const (
// extGoTypeName is used to override a generated typename for something.
extGoTypeName = "x-go-type-name"
extPropGoJsonIgnore = "x-go-json-ignore"
extGoEmbedding = "x-go-embedding"
extPropOmitEmpty = "x-omitempty"
extPropOmitZero = "x-omitzero"
extPropExtraTags = "x-oapi-codegen-extra-tags"
Expand Down
6 changes: 4 additions & 2 deletions pkg/codegen/merge_schemas.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import (

// MergeSchemas merges all the fields in the schemas supplied into one giant schema.
// The idea is that we merge all fields together into one schema.
func MergeSchemas(allOf []*openapi3.SchemaRef, path []string) (Schema, error) {
func MergeSchemas(schema *openapi3.Schema, path []string) (Schema, error) {
allOf := schema.AllOf

// If someone asked for the old way, for backward compatibility, return the
// old style result.
if globalState.options.Compatibility.OldMergeSchemas {
if globalState.options.Compatibility.OldMergeSchemas || schema.Extensions[extGoEmbedding] == true {
return mergeSchemasV1(allOf, path)
}
return mergeSchemas(allOf, path)
Expand Down
2 changes: 1 addition & 1 deletion pkg/codegen/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ func GenerateGoSchema(sref *openapi3.SchemaRef, path []string) (Schema, error) {
// so that in a RESTful paradigm, the Create operation can return
// (object, id), so that other operations can refer to (id)
if schema.AllOf != nil {
mergedSchema, err := MergeSchemas(schema.AllOf, path)
mergedSchema, err := MergeSchemas(schema, path)
if err != nil {
return Schema{}, fmt.Errorf("error merging schemas: %w", err)
}
Expand Down