Defining reusable schemas in Avro

Deepti Mittal
2 min readAug 31, 2020

--

In one of my project Avro schemas was very complex and they will run with 50 or more fields. Lots of schemas will share the fields and less than 10 fields will be unique for a individual schemas.

It was quite exhausting to maintain different schemas when one or more fields will change.

That’s where I figured out that you can divide the schemas into multiple and make them reusable across multiple schemas.

How to define multiple Avro schema

I have defined a very short schema to show the syntax where one complex type uses another one.

Here is Author schema below:

{
"namespace": "com.deepti.sample.avro.schema",
"type": "record",
"name": "Author",
"fields": [
{
"name": "id",
"type": "int"
},
{
"name": "name",
"type": "string"
},
{
"name":"publication",
"type":"string"
}
]
}

Now lets define Book Schema which used Author schema:

{
"namespace": "com.deepti.sample.avro.schema",
"type": "record",
"name": "Book",
"fields": [
{
"name": "id",
"type": "int"
},
{
"name": "name",
"type": "string"
},
{
"name":"author",
"type":"com.deepti.sample.avro.schema.Author"
},
{
"name":"publication",
"type":"string"
}
]
}

Now we will define library schema which will use both Author and Book schema:

{
"namespace": "com.deepti.sample.avro.schema",
"type": "record",
"name": "Library",
"fields": [
{
"name": "id",
"type": "int"
},
{
"name": "owner",
"type": "string"
},
{
"name":"books",
"type":"com.deepti.sample.avro.schema.Book"
},
{
"name":"authors",
"type":"com.deepti.sample.avro.schema.Author"
},
{
"name":"address",
"type":"string"
}
]
}

So you can see how type will point to type of other schema.

Gradle tasks for generating Avro classes

In Avro where one file is depended on other we have to make sure that dependencies are met before generating classes for dependent schemas. For above example, below could be the gradle tasks:

import com.commercehub.gradle.plugin.avro.GenerateAvroJavaTask
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.commercehub.gradle.plugin:gradle-avro-plugin:0.20.0"
}
}
tasks.register("generateAvro", GenerateAvroJavaTask) {
source("src/main/resources/avro/author.avsc")
source("src/main/resources/avro/book.avsc")
source("src/main/resources/avro/library.avsc")
outputDir = file("src/main/java/")
}

--

--

Deepti Mittal

I am working as software engineer in Bangalore for over a decade. Love to solve core technical problem and then blog about it.