-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Description
Problem
Due to the way that Go's JSON marshalling works, the standard way to make a field not marshal, if it was not specified, was to use a pointer, and a JSON tag of omitempty:
type Response struct {
UpdatedAt *time.Time `json:"updated_at,omitempty"`
}This is the default behaviour within oapi-codegen, and the expectation within the Go community, but it can be unwieldy.
Over the years, we've had a number of requests to make this easier to work with, in particular for folks who don't want to be dealing with pointers to things, or where there are i.e. pointers to slices:
- Is there a way to apply "x-go-type-skip-optional-pointer": true to the entire oapi code generation process? #1460
- feat(output-options): add
prefer-skip-optional-pointerto default to skipping optional pointers #1694 - Don't use pointer to slice of types #1561
(not exhaustive)
We support the field-level extension, x-go-type-skip-optional-pointer, on fields within a spec, such as:
ClientWithExtension:
type: object
required:
- name
properties:
name:
type: string
id:
type: number
x-go-type-skip-optional-pointer: trueBut this gets repetitive.
Solution
However, with the upcoming Go 1.24 release, this is something that can now handle with the new changes to encoding/json which introduces omitzero (proposal)
This would allow us to no longer provide a pointer for a type that is optional, when we can instead omitzero the zero value.
What about previous versions of Go?
This would only be intended for use with Go 1.24+ codebases.
Does this require everyone upgrade to Go 1.24?
No, the intent is that we either:
- make this an opt-in flag, via
output-options - auto-detect the
goversion that the parentgo.mod- if present - is using, and if 1.24+, useomitzero, rather than optional pointers
Out of scope
Additionally - and not part of this proposal - is that there are performance implications where you may want to use a pointer for a type, or may not.