chrusty / protoc-gen-jsonschema

Protobuf to JSON-Schema compiler
Apache License 2.0
496 stars 101 forks source link

Render protobuf oneof as json schema oneOf #56

Closed patrick-rotsaert closed 3 years ago

patrick-rotsaert commented 3 years ago

When converting the following proto file:

syntax="proto3";

package org.example;

message Foo {
    oneof choice {
        Bar bar = 1;
        Baz baz = 2;
    }

    message Bar {
        int32 foo = 1;
    }

    message Baz {
        string foo = 1;
    }
}

then the resulting json schema is:

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "properties": {
        "bar": {
            "properties": {
                "foo": {
                    "type": "integer"
                }
            },
            "additionalProperties": true,
            "type": "object"
        },
        "baz": {
            "properties": {
                "foo": {
                    "type": "string"
                }
            },
            "additionalProperties": true,
            "type": "object"
        }
    },
    "additionalProperties": true,
    "type": "object"
}

This would allow a Foo instance to contain both the bar and baz attributes, which kind of defeats the purpose of the oneof.

Would it be possible to generate a schema like this instead?

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "properties": {
        "bar": {
            "properties": {
                "foo": {
                    "type": "integer"
                }
            },
            "additionalProperties": true,
            "type": "object"
        },
        "baz": {
            "properties": {
                "foo": {
                    "type": "string"
                }
            },
            "additionalProperties": true,
            "type": "object"
        }
    },
    "oneOf": [{
            "required" : ["bar"]
        }, {
            "required" : ["baz"]
        }
    ],    
    "additionalProperties": true,
    "type": "object"
}
chrusty commented 3 years ago

Hi @patrick-rotsaert. I've had a go at this, and have a PR which hopefully does what you're after.

Would you be able to give this branch a try, and see if it meets your requirements?

It has broken one of the other unit tests though, so I'll need to figure that out before merging this.

Anyway let me know how you get on, and thanks for your interest!

patrick-rotsaert commented 3 years ago

Hi @chrusty, your change does exactly what I needed. Thanks a lot.

chrusty commented 3 years ago

This is merged and included in the latest release (https://github.com/chrusty/protoc-gen-jsonschema/releases/tag/0.9.9)

chrusty commented 3 years ago

Hey @patrick-rotsaert, had to re-open this one as it has caused some issues elsewhere. I'm planning on putting the new oneOf interpretation behind a feature flag. You'll be able to use it just fine, the only difference is you'll need to use an extra command-line option when generating your oneOf schemas. Probably a number of people (including myself) had made assumptions around how oneOf was interpreted.

chrusty commented 3 years ago

@patrick-rotsaert see the new release: https://github.com/chrusty/protoc-gen-jsonschema/releases/tag/0.9.10