Class SchemaBuilder

java.lang.Object
org.apache.avro.SchemaBuilder

public class SchemaBuilder extends Object

A fluent interface for building Schema instances. The flow of the API is designed to mimic the Avro Schema Specification

For example, the below JSON schema and the fluent builder code to create it are very similar:
 {
   "type": "record",
   "name": "HandshakeRequest", "namespace":"org.apache.avro.ipc",
   "fields": [
     {"name": "clientHash",
      "type": {"type": "fixed", "name": "MD5", "size": 16}},
     {"name": "clientProtocol", "type": ["null", "string"]},
     {"name": "serverHash", "type": "MD5"},
     {"name": "meta", "type": ["null", {"type": "map", "values": "bytes"}]}
   ]
 }
 
 Schema schema = SchemaBuilder.record("HandshakeRequest").namespace("org.apache.avro.ipc").fields().name("clientHash")
     .type().fixed("MD5").size(16).noDefault().name("clientProtocol").type().nullable().stringType().noDefault()
     .name("serverHash").type("MD5").noDefault().name("meta").type().nullable().map().values().bytesType().noDefault()
     .endRecord();
 

Usage Guide
SchemaBuilder chains together many smaller builders and maintains nested context in order to mimic the Avro Schema specification. Every Avro type in JSON has required and optional JSON properties, as well as user-defined properties.

Selecting and Building an Avro Type
The API analogy for the right hand side of the Avro Schema JSON
 "type":
 
is a SchemaBuilder.TypeBuilder, SchemaBuilder.FieldTypeBuilder, or SchemaBuilder.UnionFieldTypeBuilder, depending on the context. These types all share a similar API for selecting and building types.

Primitive Types
All Avro primitive types are trivial to configure. A primitive type in Avro JSON can be declared two ways, one that supports custom properties and one that does not:
 {"type":"int"}
 {"type":{"name":"int"}}
 {"type":{"name":"int", "customProp":"val"}}
 
The analogous code form for the above three JSON lines are the below three lines:
  .intType()
  .intBuilder().endInt()
  .intBuilder().prop("customProp", "val").endInt()
 
Every primitive type has a shortcut to create the trivial type, and a builder when custom properties are required. The first line above is a shortcut for the second, analogous to the JSON case.
Named Types
Avro named types have names, namespace, aliases, and doc. In this API these share a common parent, SchemaBuilder.NamespacedBuilder. The builders for named types require a name to be constructed, and optional configuration via:
  • SchemaBuilder.NamedBuilder.doc()
  • SchemaBuilder.NamespacedBuilder.namespace(String)
  • SchemaBuilder.NamedBuilder.aliases(String...)
  • SchemaBuilder.PropBuilder.prop(String, String)
  • Each named type completes configuration of the optional properties with its own method:

  • SchemaBuilder.FixedBuilder.size(int)
  • SchemaBuilder.EnumBuilder.symbols(String...)
  • SchemaBuilder.RecordBuilder.fields()
  • Example use of a named type with all optional parameters:
     .enumeration("Suit").namespace("org.apache.test")
       .aliases("org.apache.test.OldSuit")
       .doc("CardSuits")
       .prop("customProp", "val")
       .symbols("SPADES", "HEARTS", "DIAMONDS", "CLUBS")
     
    Which is equivalent to the JSON:
     { "type":"enum",
       "name":"Suit", "namespace":"org.apache.test",
       "aliases":["org.apache.test.OldSuit"],
       "doc":"Card Suits",
       "customProp":"val",
       "symbols":["SPADES", "HEARTS", "DIAMONDS", "CLUBS"]
     }
     
    Nested Types
    The Avro nested types, map and array, can have custom properties like all avro types, are not named, and must specify a nested type. After configuration of optional properties, an array or map builds or selects its nested type with SchemaBuilder.ArrayBuilder.items() and SchemaBuilder.MapBuilder.values(), respectively.
    Fields
    SchemaBuilder.RecordBuilder.fields() returns a SchemaBuilder.FieldAssembler for defining the fields of the record and completing it. Each field must have a name, specified via SchemaBuilder.FieldAssembler.name(String), which returns a SchemaBuilder.FieldBuilder for defining aliases, custom properties, and documentation of the field. After configuring these optional values for a field, the type is selected or built with SchemaBuilder.FieldBuilder.type().

    Fields have default values that must be specified to complete the field. SchemaBuilder.FieldDefault.noDefault() is available for all field types, and a specific method is available for each type to use a default, for example SchemaBuilder.IntDefault.intDefault(int)

    There are field shortcut methods on SchemaBuilder.FieldAssembler for primitive types. These shortcuts create required, optional, and nullable fields, but do not support field aliases, doc, or custom properties.

    Unions
    Union types are built via SchemaBuilder.TypeBuilder.unionOf() or SchemaBuilder.FieldTypeBuilder.unionOf() in the context of type selection. This chains together multiple types, in union order. For example:
     .unionOf()
       .fixed("IPv4").size(4).and()
       .fixed("IPv6").size(16).and()
       .nullType().endUnion()
     
    is equivalent to the Avro schema JSON:
     [
       {"type":"fixed", "name":"IPv4", "size":4},
       {"type":"fixed", "name":"IPv6", "size":16},
       "null"
     ]
     
    In a field context, the first type of a union defines what default type is allowed.

    Unions have two shortcuts for common cases. nullable() creates a union of a type and null. In a field type context, optional() is available and creates a union of null and a type, with a null default. The below two are equivalent:
       .unionOf().intType().and().nullType().endUnion()
       .nullable().intType()
     
    The below two field declarations are equivalent:
       .name("f").type().unionOf().nullType().and().longType().endUnion().nullDefault()
       .name("f").type().optional().longType()
     
    Explicit Types and Types by Name
    Types can also be specified explicitly by passing in a Schema, or by name:
       .type(Schema.create(Schema.Type.INT)) // explicitly specified
       .type("MD5")                       // reference by full name or short name
       .type("MD5", "org.apache.avro.test")  // reference by name and namespace
     
    When a type is specified by name, and the namespace is absent or null, the namespace is inherited from the enclosing context. A namespace will propagate as a default to child fields, nested types, or later defined types in a union. To specify a name that has no namespace and ignore the inherited namespace, set the namespace to "".

    builder(String) returns a type builder with a default namespace. builder() returns a type builder with no default namespace.

    • Method Details

      • builder

        public static SchemaBuilder.TypeBuilder<Schema> builder()
        Create a builder for Avro schemas.
      • builder

        public static SchemaBuilder.TypeBuilder<Schema> builder(String namespace)
        Create a builder for Avro schemas with a default namespace. Types created without namespaces will inherit the namespace provided.
      • record

        public static SchemaBuilder.RecordBuilder<Schema> record(String name)
        Create a builder for an Avro record with the specified name. This is equivalent to:
         builder().record(name);
         
        Parameters:
        name - the record name
      • enumeration

        public static SchemaBuilder.EnumBuilder<Schema> enumeration(String name)
        Create a builder for an Avro enum with the specified name and symbols (values). This is equivalent to:
         builder().enumeration(name);
         
        Parameters:
        name - the enum name
      • fixed

        public static SchemaBuilder.FixedBuilder<Schema> fixed(String name)
        Create a builder for an Avro fixed type with the specified name and size. This is equivalent to:
         builder().fixed(name);
         
        Parameters:
        name - the fixed name
      • array

        public static SchemaBuilder.ArrayBuilder<Schema> array()
        Create a builder for an Avro array This is equivalent to:
         builder().array();
         
      • map

        public static SchemaBuilder.MapBuilder<Schema> map()
        Create a builder for an Avro map This is equivalent to:
         builder().map();
         
      • unionOf

        Create a builder for an Avro union This is equivalent to:
         builder().unionOf();
         
      • nullable

        public static SchemaBuilder.BaseTypeBuilder<Schema> nullable()
        Create a builder for a union of a type and null. This is a shortcut for:
         builder().nullable();
         
        and the following two lines are equivalent:
         nullable().intType();
         
         unionOf().intType().and().nullType().endUnion();