Skip to content

Commit 22ccd05

Browse files
Jamie Tannajamietanna
authored andcommitted
docs(output-options): document how to skip the "optional pointer"
As a follow-up from the two options we've recently introduced for this. This adds an anchor so we can reference it more easily than the GitHub-generated name for the long heading.
1 parent b72bb2a commit 22ccd05

1 file changed

Lines changed: 84 additions & 0 deletions

File tree

README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2462,6 +2462,8 @@ You can see this in more detail in [the example code](examples/extensions/xgotyp
24622462

24632463
### `x-go-type-skip-optional-pointer` - do not add a pointer type for optional fields in structs
24642464

2465+
<a name="ext-x-go-type-skip-optional-pointer"></a>
2466+
24652467
> [!TIP]
24662468
> If you prefer this behaviour, and prefer to not have to annotate your whole OpenAPI spec for this behaviour, you can use `output-options.prefer-skip-optional-pointer=true` to default this behaviour for all fields.
24672469
>
@@ -3732,6 +3734,88 @@ func (a Thing) MarshalJSON() ([]byte, error) {
37323734

37333735
</details>
37343736

3737+
## Globally skipping the "optional pointer"
3738+
3739+
One of the key things `oapi-codegen` does is to use an "optional pointer", following idiomatic Go practices, to indicate that a field/type is optional.
3740+
3741+
This can be tuned on a per-field basis, using the [`x-go-type-skip-optional-pointer` extension](#ext-x-go-type-skip-optional-pointer), but it can be a bit repetitive, or can be more complex when using an OpenAPI Overlay.
3742+
3743+
As of `oapi-codegen` v2.5.0, this can be tuned in two specific ways, via the following Output Options:
3744+
3745+
- `prefer-skip-optional-pointer`: a global default that you do _not_ want the "optional pointer" generated. Optional fields will not have an "optional pointer", and will have an `omitempty` JSON tag
3746+
- `prefer-skip-optional-pointer-with-omitzero`: when used in conjunction with `prefer-skip-optional-pointer-with-omitzero`, any optional fields are generated with an `omitzero` JSON tag. **Requires Go 1.24+**
3747+
3748+
In both cases, there is control on a per-field level to set `x-go-type-skip-optional-pointer: false` or `x-omitzero: false` to undo these to field(s).
3749+
3750+
For example, when combining both options:
3751+
3752+
```yaml
3753+
# yaml-language-server: $schema=https://raw.githubusercontent.com/oapi-codegen/oapi-codegen/HEAD/configuration-schema.json
3754+
package: preferskipoptionalpointerwithomitzero
3755+
output: gen.go
3756+
generate:
3757+
# ...
3758+
output-options:
3759+
# ...
3760+
prefer-skip-optional-pointer: true
3761+
prefer-skip-optional-pointer-with-omitzero: true
3762+
```
3763+
3764+
When we have the following spec:
3765+
3766+
```yaml
3767+
openapi: "3.0.0"
3768+
info:
3769+
version: 1.0.0
3770+
title: prefer-skip-optional-pointer-with-omitzero
3771+
components:
3772+
schemas:
3773+
ClientWithExtension:
3774+
type: object
3775+
required:
3776+
- name
3777+
properties:
3778+
name:
3779+
description: This field is required, so will never have an optional pointer, nor `omitzero`.
3780+
type: string
3781+
id:
3782+
description: This field is optional, but the `prefer-skip-optional-pointer` Output Option ensures that this should not have an optional pointer. However, it will receive `omitzero`.
3783+
type: number
3784+
pointer_id:
3785+
type: number
3786+
description: This field should have an optional pointer, as the field-level definition of `x-go-type-skip-optional-pointer` overrides the `prefer-skip-optional-pointer` Output Option. This will also not receive an `omitzero`.
3787+
# NOTE that this overrides the global preference
3788+
x-go-type-skip-optional-pointer: false
3789+
no_omit:
3790+
type: number
3791+
description: This field is optional, but the `prefer-skip-optional-pointer` Output Option ensures that this should not have an optional pointer. This will not receive `omitzero`, as the field-level definition of `x-omitzero` overrides the `prefer-skip-optional-pointer-with-omitzero` Output Option.
3792+
# NOTE that this overrides the global preference
3793+
x-omitzero: false
3794+
```
3795+
3796+
We then generate the following Go code:
3797+
3798+
```go
3799+
// ...
3800+
3801+
// ClientWithExtension defines model for ClientWithExtension.
3802+
type ClientWithExtension struct {
3803+
// Id This field is optional, but the `prefer-skip-optional-pointer` Output Option ensures that this should not have an optional pointer. However, it will receive `omitzero`.
3804+
Id float32 `json:"id,omitempty,omitzero"`
3805+
3806+
// Name This field is required, so will never have an optional pointer, nor `omitzero`.
3807+
Name string `json:"name"`
3808+
3809+
// NoOmit This field is optional, but the `prefer-skip-optional-pointer` Output Option ensures that this should not have an optional pointer. This will not receive `omitzero`, as the field-level definition of `x-omitzero` overrides the `prefer-skip-optional-pointer-with-omitzero` Output Option.
3810+
NoOmit float32 `json:"no_omit,omitempty"`
3811+
3812+
// PointerId This field should have an optional pointer, as the field-level definition of `x-go-type-skip-optional-pointer` overrides the `prefer-skip-optional-pointer` Output Option. This will also not receive an `omitzero`.
3813+
PointerId *float32 `json:"pointer_id,omitempty"`
3814+
}
3815+
```
3816+
3817+
You can see this in more detail in [the example code for `prefer-skip-optional-pointer`](examples/output-options/preferskipoptionalpointer/) and [example code for `prefer-skip-optional-pointer-with-omitzero`](examples/output-options/preferskipoptionalpointerwithomitzero/)
3818+
37353819
## Changing the names of generated types
37363820

37373821
As of `oapi-codegen` v2.2.0, it is now possible to use the `output-options` configuration's `name-normalizer` to define the logic for how to convert an OpenAPI name (i.e. an Operation ID or a Schema name) and construct a Go type name.

0 commit comments

Comments
 (0)