fix: set pointer as a 3.1 reference type - #838
Conversation
025f6fa to
2bca397
Compare
|
It does solve the issue but also introduces a regression. Nullability should be scoped to the user of referenced types and not drill down into the type. For example: package main
import (
"encoding/json"
"fmt"
"github.com/go-fuego/fuego"
)
type Owner struct {
Name string `json:"name"`
}
type Widget struct {
Name *string `json:"name"` // pointer -> nullable scalar
Tags []string `json:"tags"` // slice
Owner *Owner `json:"owner"` // pointer to a named struct -> $ref
}
func main() {
s := fuego.NewServer()
fuego.Get(s, "/widget", func(c fuego.ContextNoBody) (Widget, error) {
return Widget{}, nil
})
// Owner is also returned on its own, where it is never null.
fuego.Get(s, "/owner", func(c fuego.ContextNoBody) (Owner, error) {
return Owner{}, nil
})
doc := s.OpenAPI.Description()
fmt.Println("openapi:", doc.OpenAPI)
for _, name := range []string{"Widget", "Owner"} {
out, _ := json.MarshalIndent(doc.Components.Schemas[name].Value, "", " ")
fmt.Printf("%s: %s\n", name, out)
}
}now produces: "Owner": {
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
],
- "type": "object"
+ "type": [
+ "object",
+ "null"
+ ]
},
"Widget": {
"description": "Widget schema",
"properties": {
"name": {
- "nullable": true,
- "type": "string"
+ "type": [
+ "string",
+ "null"
+ ]
},
"owner": {
"$ref": "#/components/schemas/Owner"
},
"tags": {
"items": {
"type": "string"
},
"type": [
"array",
"null"
]
}
},
"required": [
"name",
"owner",
"tags"
],
"type": "object"
},
Note the addition of |
|
Ah, I see. I'm not sure this is gonna be possible to do without having to fight with kin's implementation as it doesn't seem 3.1 is completely supported either... 🤔 |
|
Interesting, I had Claude build this shim to unblock us. It seems to solve the issues we were seeing with our generator. then is called |
|
Right, I can't see a way of doing this at generation time. Let me read through some kin stuff and see where they are at. In the meantime, some post processing thing would be nice, and makes it conceptually easier to work with specs after output than having to use schemacustomizer Could be helpful in this case. |
|
Yeah I have quite a few shims to get the spec into a format I want (mostly to clean up generator output/behavior and to match my old NestJS implementation) including non nullable arrays, content negotiation parameters, promoting enum structs that I have, and setting binary payloads to the correct type. A build in post processing driver would be extremely useful in this case |
|
I think I'm gonna close this. Let's leave the issue open though. Looking at kin it may not be that hard to get their output doing this or maybe provide an option to do it. |
2bca397 to
0fbf3df
Compare
|
@bwees I looked into kin-openapi some more. They don't seem to have move their openapigen package over yet. They do also seem to want to support both 3.0 and 3.1. I'm probably gonna look into doing it for them, but it may take bit cause I'm not sure what they would want a solution to look like. What your thoughts on this. i'll probably keep the engine option or it's probably better as an openapi option to walk. I can then export a func called something |
|
Found myself adding this in for my day job today, for probably a similar reason to yours s.OpenAPI.Description().WalkSchemas(func(_ string, ref *openapi3.SchemaRef) error {
schema := ref.Value
if schema.Nullable && schema.Type != nil && !schema.Type.Includes("null") {
*schema.Type = append(*schema.Type, "null")
schema.Nullable = false
}
return nil
})
if onlySpec {
s.OutputOpenAPISpec()
return nil
}I think an option would be pretty useful. |
|
agreed, I like this |
Closes #810
@bwees
I believe this will solve your issue