Nullable nested object support
siviae opened this issue · 0 comments
siviae commented
Hello! Thanks a lot for your work.
Right now I am trying to use this tool during my work and I have a problem with using oneOf to support passing null json values. For example, when I use the following schema:
{
"title": "Repro",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"nested": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/definitions/Nested"
}
]
}
},
"definitions": {
"Nested": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
]
}
}
}
I've got the following output:
type Nested struct {
// Name corresponds to the JSON schema field "name".
Name string `json:"name" yaml:"name" mapstructure:"name"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *Nested) UnmarshalJSON(b []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(b, &raw); err != nil {
return err
}
if v, ok := raw["name"]; !ok || v == nil {
return fmt.Errorf("field name in Nested: required")
}
type Plain Nested
var plain Plain
if err := json.Unmarshal(b, &plain); err != nil {
return err
}
*j = Nested(plain)
return nil
}
type Repro struct {
// Nested corresponds to the JSON schema field "nested".
Nested interface{} `json:"nested,omitempty" yaml:"nested,omitempty" mapstructure:"nested,omitempty"`
}
which is very inconvenient to use, since json.Unmarshal
does not know, which type to use for nested
field.
When I use the following schema:
{
"title": "Repro",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"nested": {
"$ref": "#/definitions/Nested"
}
},
"definitions": {
"Nested": {
"type": "object",
"properties": {
"name": {
"type": "string"
}
},
"required": [
"name"
]
}
}
}
I have the result I want, which is
type Nested struct {
// Name corresponds to the JSON schema field "name".
Name string `json:"name" yaml:"name" mapstructure:"name"`
}
// UnmarshalJSON implements json.Unmarshaler.
func (j *Nested) UnmarshalJSON(b []byte) error {
var raw map[string]interface{}
if err := json.Unmarshal(b, &raw); err != nil {
return err
}
if v, ok := raw["name"]; !ok || v == nil {
return fmt.Errorf("field name in Nested: required")
}
type Plain Nested
var plain Plain
if err := json.Unmarshal(b, &plain); err != nil {
return err
}
*j = Nested(plain)
return nil
}
type Repro struct {
// Nested corresponds to the JSON schema field "nested".
Nested *Nested `json:"nested,omitempty" yaml:"nested,omitempty" mapstructure:"nested,omitempty"`
}
however, I want the {"nested": null}
json object to be valid both in terms of schema and the parser, not just the parser.
I understand that full support of oneOf
requires a lot of work, however I think that supporting this special case could be quite easy.