Skip to content
This repository was archived by the owner on Apr 14, 2026. It is now read-only.

Commit d24950b

Browse files
committed
Update README
1 parent d75333d commit d24950b

1 file changed

Lines changed: 32 additions & 104 deletions

File tree

experimental/README.md

Lines changed: 32 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -12,118 +12,41 @@ What is working:
1212
- All model, client and server generation as in earlier versions.
1313
- We have added Webhook and Callback support, please see `./examples`, which contains the ubiquitous OpenAPI pet shop implemented in all supported servers
1414
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.
1615
- 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+
1823
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.
2027

2128
## Differences in V3
2229

2330
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
2431
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
2532
file Issues.
2633

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.
37+
38+
| V2 | This version | Scope | Purpose |
39+
|---|----------------------------------------|---|---|
40+
| `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`). |
47+
| `x-enum-varnames` / `x-enumNames` | `x-oapi-codegen-enum-varnames` | Schema (enum) | Override generated enum constant names. |
48+
| `x-deprecated-reason` | `x-oapi-codegen-deprecated-reason` | Schema, Operation | Provide a deprecation reason for documentation. |
49+
| `x-order` | `x-oapi-codegen-order` | Property | Control field ordering in generated structs. |
12750

12851
### OpenAPI V3.1 Feature Support
12952

@@ -151,6 +74,11 @@ audit requirements. V3 embeds all necessary helper functions and helper types in
15174
handle arbitrary parameters, but rather very specific functions for each kind of parameter, and we call the correct little helper versus a generic
15275
runtime helper.
15376

77+
We still use the code generator to produce a pre-generated `runtime` package, which you are
78+
welcome to use. It will always be consistent with the code generated with the corresponding
79+
oapi-codegen. If you have lots of OpenAPI specs locally, you can also generate the runtime
80+
package, as we do, in your own code to avoid bloat.
81+
15482
### Models now support default values configured in the spec
15583

15684
Every model which we generate supports an `ApplyDefaults()` function. It recursively applies defaults on
@@ -160,7 +88,7 @@ unrelated to what we're doing. Please let me know if this feature is causing tro
16088

16189
## Installation
16290

163-
Go 1.24 is required, install like so:
91+
Go 1.25 is required, install like so:
16492

16593
go get -tool github.com/oapi-codegen/oapi-codegen-exp/experimental/cmd/oapi-codegen@latest
16694

0 commit comments

Comments
 (0)