Reputation: 11
I'm working on something that has api definition defined complying with openapi 3.0.0 Asper openapi 3.0.0, the oneOf type field can take value of any one of the mentioned type.
pet:
oneOf:
- $ref: '#/components/schemas/Cat'
- $ref: '#/components/schemas/Dog'
components:
schemas:
Dog:
type: object
properties:
bark:
type: boolean
breed:
type: string
enum: [Dingo, Husky, Retriever, Shepherd]
Cat:
type: object
properties:
hunts:
type: boolean
age:
type: integer
As per swagger, the correct json schema for this can be {"pet":{"hunts":false,"age":3}} if the pet type is cat, and if it's a dog, it will be {"pet":{"bark":true,"breed":"Husky"}}
It doesn't explicitly specify the type, and assumes that the server can decode it depending on the fields present.
I am using protobuf to manage the data types since i also need to send this to different microservices using grpc, for this kind of example i thought of using oneOf from proto.
the definition of the proto is
message pet{
oneof pet{
Cat cat = 1;
Dog dog = 2;
}
}
message Cat {
boolean hunts = 1;
int age = 2;
}
message Dog {
boolean bark = 1;
string breed =2;
}
But unmarshling the json into pet type fails since it's expecting the json message has to have a field pet, and then dog or cat i guess.
Is there any other convention followed for the oneof type from openapi spec to golang?
Is there any other convention followed for the oneof type from openapi spec to golang?
Upvotes: 1
Views: 288
Reputation: 40296
You're correct the the JSON equivalent of the Protobuf example you provide does not match the OpenAPI:
[
{
"dog":{
"bark":true,
"breed":"Border Collie"
}
},
{
"cat":{
"hunts":true,
"age":4
}
}
]
You could consider using Google's Well-known Types, specifically Value
message M {
google.protobuf.Value pet = 1;
}
Unfortunately, you lose the type-safety that Protobuf wants to enforce using oneof
but, you get the (typeless) JSON that you want:
[
{
"pet":{
"bark":true,
"breed":"Border Collie"
}
},
{
"pet":{
"hunts":true,
"age":4
}
}
]
Upvotes: 0