-
-
Notifications
You must be signed in to change notification settings - Fork 152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make pointers and/or OmittableNullable
nullable in the generated OpenAPI spec
#238
Comments
@gregoryjjb thanks for the question! Couple of things to clarify:
Thanks! |
My underlying goal: values that are optional/nullable in Go should take as little effort as possible to be marked as such in the spec and typescript types, to reduce chances of spec-to-Go mismatch. ("As little effort as possible" means ideally I don't need to tag each pointer field as optional manually) |
Looks like Edit: also https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0 |
It seems that to support the 3.1 way of doing nulllable: type:
- "string"
- "null" then func (n *OmittableNullable[T]) Schema(r huma.Registry) *huma.Schema {
s := r.Schema(reflect.TypeOf(n.Val), true, "")
// This would be the thing to do I think?
s.Type = append(s.Type, "null")
return s
} |
@gregoryjjb thanks, yeah this looks doable but isn't a small fix. I need to dig into what updating I kind of hate this, but as a temporary workaround you can actually use the func (o OmittableNullable[T]) Schema(r huma.Registry) *huma.Schema {
s := r.Schema(reflect.TypeOf(o.Value), true, "")
s.Extensions = map[string]any{
"type": []string{s.Type, "null"},
}
return s
} |
That does do the trick, thanks! Last question: is it possible to make it do this by default for native pointer types? Right now, a Go Here's how I think of the natural defaults:
|
I had a go at implementing the above rules and it's actually tricky, because the fact that |
@gregoryjjb yes this seems kind of tricky overall. I'll have to take some time soon and dig deeper into it. For now I'll leave this open as a feature request and anyone is welcome to pitch in! |
I wonder if it would be simpler to support it using something like this, but I'm not sure how SDK generators would handle it: MyType:
oneOf:
- type: "null"
- type: string The advantage is we already support basic |
Tested this with Orval and it does produce usable results: "200": {
Content: map[string]*huma.MediaType{
"application/json": {
Schema: &huma.Schema{
Type: huma.TypeObject,
Properties: map[string]*huma.Schema{
"field": {
OneOf: []*huma.Schema{
{
Type: "string",
},
{
Type: "null",
},
},
},
},
Required: []string{"field"},
},
},
},
}, produces the following Typescript: export type TestNullable200Field = string | null;
export type TestNullable200 = {
field: TestNullable200Field;
}; Another thing I'm experimenting with Since Go doesn't support union types anyway, what if the nullability is a special case in Huma that marshals to an OpenAPI slice? // SchemaType represents a JSON Schema type. While JSON Schema supports union
// types by way of an array of types, Go doesn't support union types, so this
// SchemaType will only marshal to an array if it is nullable. e.g.:
// { Name: "string", Nullable: false } -> { "type": "string" }
// { Name: "string", Nullable: true } -> { "type": ["string", "null"] }
type SchemaType struct {
Name string
Nullable bool
}
type Schema struct { //nolint: musttag
Type *SchemaType `yaml:"type,omitempty"`
...
} Validation could be updated to allow This explicitly avoids supporting the union type arrays in a general way but maybe that's better for Go? I'm still not sure what to do about what is the most difficult part IMO, which is how to change the nullability of a Schema based on the |
One thing I am not a huge fan of is the need for omitempty to get a non-required field in a request body. type CreateDocumentRequest struct {
actor.Actor
Body struct {
MatterID *string `json:"MatterID,omitempty"`
Title *string `json:"Title,omitempty"`
Description *string `json:"Description,omitempty"`
WorkspaceID string
UploadID string
}
} As you can see, it forces me to repeat the field name in the json struct tag. If I use |
Would you be open or is it possible to add a custom tag like |
@gregoryjjb @lazharichir @amsal please take a look at #351 and let me know what you think. |
Will check this tonight against my three repos that use Huma and would definitely benefit from this! |
I came across this thread looking for a way to set the default value for an nullable field to "null". I'm not sure there is a way to do this. |
How can I set fields to be nullable in the generated spec? I can't find any way to set nullability on a Schema.
Ideally I'd like to make pointers always nullable (to match my Go code as closely as possible), and/or have custom types like the
OmittableNullable
example generate as nullable.Thanks in advance ❤️
The text was updated successfully, but these errors were encountered: