You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Apr 14, 2026. It is now read-only.
- All model, client and server generation as in earlier versions.
13
13
- We have added Webhook and Callback support, please see `./examples`, which contains the ubiquitous OpenAPI pet shop implemented in all supported servers
14
14
and examples of webhooks and callbacks implemented on top of the `http.ServeMux` server, with no additional imports.
15
-
- Model generation of `allOf`, `anyOf`, `oneOf` is much more robust, since these were a source of many problems in earlier versions.
16
15
- Echo V5 support has been added (Go 1.25 required)
17
-
16
+
- The `runtime` has changed a lot. By default, we generate all the needed runtime
17
+
functions into your generated code. You can, optionally, generate your own runtime
18
+
package locally, to avoid duplication between multiple openapi specifications. This
19
+
was done because the version pinning between runtime and the codegen was exceedingly
20
+
annoying, so now, the runtime is embedded into the generator itself, and there is
21
+
no versioning issue.
22
+
18
23
What is missing:
19
-
- We have not yet created any runtime code like request validation middleware.
24
+
- Middleware, this is for someone else to solve.
25
+
- Good documentation. You'll have to read over the config file code to see how
26
+
to configure.
20
27
21
28
## Differences in V3
22
29
23
30
V3 is a brand new implementation, and may (will) contain new bugs, but also strives to fix many current, existing bugs. We've run quite a few
24
31
conformance tests against specifications in old Issues, and we're looking pretty good! Please try this out, and if it failes in some way, please
25
32
file Issues.
26
33
27
-
### Aggregate Schemas
28
-
29
-
V3 implements `oneOf`, `anyOf`, `allOf` differently. Our prior versions had pretty good handling for `allOf`, where we merge all the constituent schemas
30
-
into a schema object that contains all the fields of the originals. It makes sense, since this is composition.
31
-
32
-
`oneOf` and `anyOf` were handled by deferred parsing, where the JSON was captured into `json.RawMessage` and helper functions were created on each
33
-
type to parse the JSON as any constituent type with the user's help.
34
-
35
-
Given the following schemas:
36
-
37
-
```yaml
38
-
components:
39
-
schemas:
40
-
Cat:
41
-
type: object
42
-
properties:
43
-
name:
44
-
type: string
45
-
color:
46
-
type: string
47
-
Dog:
48
-
type: object
49
-
properties:
50
-
name:
51
-
type: string
52
-
color:
53
-
type: string
54
-
Fish:
55
-
type: object
56
-
properties:
57
-
species:
58
-
type: string
59
-
isSaltwater:
60
-
type: boolean
61
-
NamedPet:
62
-
anyOf:
63
-
- $ref: '#/components/schemas/Cat'
64
-
- $ref: '#/components/schemas/Dog'
65
-
SpecificPet:
66
-
oneOf:
67
-
- $ref: '#/components/schemas/Cat'
68
-
- $ref: '#/components/schemas/Dog'
69
-
- $ref: '#/components/schemas/Fish'
70
-
```
71
-
72
-
#### V2 output
73
-
74
-
V2 generates both `NamedPet` (anyOf) and `SpecificPet` (oneOf) identically as opaque wrappers around `json.RawMessage`:
75
-
76
-
```go
77
-
type NamedPet struct {
78
-
union json.RawMessage
79
-
}
80
-
81
-
type SpecificPet struct {
82
-
union json.RawMessage
83
-
}
84
-
```
85
-
86
-
The actual variant types are invisible at the struct level. To access the underlying data, the user must call generated helper methods:
87
-
88
-
```go
89
-
// NamedPet (anyOf) helpers
90
-
func (t NamedPet) AsCat() (Cat, error)
91
-
func (t *NamedPet) FromCat(v Cat) error
92
-
// <snip>
93
-
94
-
// SpecificPet (oneOf) helpers
95
-
96
-
func (t SpecificPet) AsFish() (Fish, error)
97
-
func (t *SpecificPet) FromFish(v Fish) error
98
-
func (t *SpecificPet) MergeFish(v Fish) error
99
-
// <snip>
100
-
```
101
-
102
-
Note that `anyOf` and `oneOf` produce identical types and method signatures; there is no semantic difference in the generated code.
103
-
104
-
#### V3 output
105
-
106
-
V3 generates structs with exported pointer fields for each variant, making the union members visible at the type level. Crucially, `anyOf` and `oneOf` now have different marshal/unmarshal semantics.
107
-
108
-
**`anyOf` (NamedPet)** — `MarshalJSON` merges all non-nil variants into a single JSON object. `UnmarshalJSON` tries every variant and keeps whichever succeed:
109
-
110
-
```go
111
-
type NamedPet struct {
112
-
Cat *Cat
113
-
Dog *Dog
114
-
}
115
-
116
-
```
117
-
118
-
**`oneOf` (SpecificPet)** — `MarshalJSON` returns an error unless exactly one field is non-nil. `UnmarshalJSON` returns an error unless the JSON matches exactly one variant:
119
-
120
-
```go
121
-
type SpecificPet struct {
122
-
Cat *Cat
123
-
Dog *Dog
124
-
Fish *Fish
125
-
}
126
-
```
34
+
### Normalized extension names
35
+
36
+
V3 normalizes all extension names under the `x-oapi-codegen-` prefix. The old names are still accepted for backwards compatibility.
|`x-go-type` + `x-go-type-import`|`x-oapi-codegen-type-override`| Schema, Property | Use an external Go type instead of generating one. V3 combines type and import into a single value: `"TypeName;import/path"`. |
41
+
|`x-go-name`|`x-oapi-codegen-name-override`| Property | Override the generated Go field name. |
42
+
|`x-go-type-name`|`x-oapi-codegen-type-name-override`| Schema | Override the generated Go type name. |
43
+
|`x-go-type-skip-optional-pointer`|`x-oapi-codegen-skip-optional-pointer`| Property | Don't wrap optional fields in a pointer. |
44
+
|`x-go-json-ignore`|`x-oapi-codegen-json-ignore`| Property | Exclude the field from JSON (`json:"-"`). |
45
+
|`x-omitempty`|`x-oapi-codegen-omitempty`| Property | Explicitly control the `omitempty` JSON tag. |
46
+
|`x-omitzero`|`x-oapi-codegen-omitzero`| Property | Add `omitzero` to the JSON tag (Go 1.24+ `encoding/json/v2`). |
0 commit comments