Skip to content

wirelessr/avroschema

Repository files navigation

Go Avro Schema Reflection

workflow Lint Go Report

This package can be used to generate Avro Schemas from Go types through reflection.

Basic Usage

The following Go type:

type Entity struct {
		AStrField    *string  `json:"a_str_field"`
		AIntField    *int     `json:"a_int_field"`
		ABoolField   *bool    `json:"a_bool_field"`
		AFloatField  *float32 `json:"a_float_field"`
		ADoubleField *float64 `json:"a_double_field"`
	}

Results in following JSON Schema:

import "github.com/wirelessr/avroschema"

avroschema.Reflect(&Entity{})
{
  "name": "Entity",
  "type": "record",
  "fields": [
    { "name": "a_str_field", "type": "string" },
    { "name": "a_int_field", "type": "int" },
    { "name": "a_bool_field", "type": "boolean" },
    { "name": "a_float_field", "type": "float" },
    { "name": "a_double_field", "type": "double" }
  ]
}

Advanced Configuration

The Reflector struct provides several configuration options:

reflector := &avroschema.Reflector{
    BeBackwardTransitive: true,  // Make all fields optional
    EmitAllFields:        true,  // Include fields without tags
    SkipTagFieldNames:    false, // Use JSON/BSON tag names
    Mapper:               nil,   // Custom type mapper
    NameMapping:          nil,   // Custom name mapping
    Namespace:           "",     // Schema namespace
}

Handling Nested Structures

The package supports nested structs and arrays:

type Address struct {
    Street string `json:"street"`
    City   string `json:"city"`
}

type Person struct {
    Name    string   `json:"name"`
    Age     int      `json:"age"`
    Address Address  `json:"address"`
    Emails  []string `json:"emails"`
}

Resulting schema:

{
  "name": "Person",
  "type": "record",
  "fields": [
    { "name": "name", "type": "string" },
    { "name": "age", "type": "int" },
    {
      "name": "address",
      "type": {
        "name": "Address",
        "type": "record",
        "fields": [
          { "name": "street", "type": "string" },
          { "name": "city", "type": "string" }
        ]
      }
    },
    { "name": "emails", "type": { "type": "array", "items": "string" } }
  ]
}

Time Handling

Time values are automatically converted to timestamp-millis:

type Event struct {
    ID        string    `json:"id"`
    Timestamp time.Time `json:"timestamp"`
}
{
  "name": "Event",
  "type": "record",
  "fields": [
    { "name": "id", "type": "string" },
    { "name": "timestamp", "type": "long", "logicalType": "timestamp-millis" }
  ]
}

Custom Type Mapping

You can implement custom type mapping:

reflector.Mapper = func(t reflect.Type) any {
    if t == reflect.TypeOf(primitive.ObjectID{}) {
        return "string"
    }
    return nil // fall back to default mapping
}

Optional Fields

Mark fields as optional with ,omitempty:

type User struct {
    Username string  `json:"username"`
    Email    *string `json:"email,omitempty"`
}
{
  "name": "User",
  "type": "record",
  "fields": [
    { "name": "username", "type": "string" },
    { "name": "email", "type": ["null", "string"] }
  ]
}

MongoDB ORM (mgm) Support

The popular MongoDB ORM, mgm, is supported:

The following Go type:

type Book struct {
		mgm.DefaultModel `bson:",inline"`
		Name             string             `json:"name" bson:"name"`
		Pages            int                `json:"pages" bson:"pages"`
		ObjId            primitive.ObjectID `json:"obj_id" bson:"obj_id"`
		ArrivedAt        primitive.DateTime `json:"arrived_at" bson:"arrived_at"`
		RefData          bson.M             `json:"ref_data" bson:"ref_data"`
		Author           []string           `json:"author" bson:"author"`
	}

The type mappings can be customized by Mapper.

import (
	"github.com/wirelessr/avroschema"
	"github.com/wirelessr/avroschema/mongo"
)

reflector := new(avroschema.Reflector)
reflector.Mapper = MgmExtension

reflector.Reflect(&Book{})

Results in following JSON Schema:

{
  "name": "Book",
  "type": "record",
  "fields": [
    { "name": "_id", "type": "string" },
    { "name": "created_at", "type": "long", "logicalType": "timestamp-millis" },
    { "name": "updated_at", "type": "long", "logicalType": "timestamp-millis" },
    { "name": "name", "type": "string" },
    { "name": "pages", "type": "int" },
    { "name": "obj_id", "type": "string" },
    { "name": "arrived_at", "type": "long", "logicalType": "timestamp-millis" },
    { "name": "ref_data", "type": "string" },
    { "name": "author", "type": "array", "items": "string" }
  ]
}

About

Generate AVRO Schemas from Go types

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages