Avro multiple record of same type in single schema
As stated in the spec:
A schema or protocol may not contain multiple definitions of a fullname.
Further, a name must be defined before it is used ("before" in the
depth-first, left-to-right traversal of the JSON parse tree, where the
types attribute of a protocol is always deemed to come "before" the
messages attribute.)
For example:
{
"type": "record",
"namespace": "my.types",
"name": "OrderBook",
"fields": [
{
"name": "bids",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "OrderBookVolume",
"fields": [
{"name": "price", "type": "double"},
{"name": "volume", "type": "double"}
]
}
}
},
{
"name": "asks",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "my.types.OrderBookVolume"
}
}
}
]
}
The first occurrence is the full schema for OrderBookVolume
. Afterwards, you can just refer to the fullname
: my.types.OrderBookVolume
.
It's also worth noting that you don't need to have a namespace for each record. It inherits it from its parent. Including it will override the namespace.
It's not well documented, but Avro allows you to reference previously defined names by using the full namespace for the name that is being referenced. In your case, the following code would result in only one class being generated, referenced by each array. It also DRYs up the schema nicely.
{
"type": "record",
"name": "OrderBook",
"namespace": "my.types",
"doc": "Test order update",
"fields": [
{
"name": "bids",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "OrderBookVolume",
"namespace": "my.types.bid",
"fields": [
{
"name": "price",
"type": "double"
},
{
"name": "volume",
"type": "double"
}
]
}
}
},
{
"name": "asks",
"type": {
"type": "array",
"items": "my.types.bid.OrderBookVolume"
}
}
]
}