linkedin / linkedin/goavro

Advice request to encode complex structure

Open
#197 6 comments 4 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
1.1k
Forks
232
PR merge metrics
No merged PRs in 30d

Description

Hi everyone,

I'm actually new in linkedin/goavro lib, and I'm trying to use the lib to encode a complex structure. I have the following code to encode a nested User structure:

package main

import (
	"encoding/json"
	"fmt"
	"time"

	hambda "github.com/hamba/avro"
	"github.com/linkedin/goavro"
)

type Phone struct {
	PhoneNumber string `avro:"phoneNumber" json:"phoneNumber"`
}

type Base struct {
	ID        string    `avro:"id" json:"id"`
	CreatedAt time.Time `avro:"createdAt" json:"createdAt"`
}

type User struct {
	Base
	Firstname string `avro:"firstName" json:"firstName"`
	Lastname  string `avro:"lastName" json:"lastName"`
	Count     int    `avro:"count" json:"count"`
	Phone     *Phone `avro:"phone" json:"phone"`
}

var mockUser = User{
	Firstname: "Maeglin",
	Lastname:  "Dev",
}

func main() {
	schema, err := hambda.ParseFiles("schema.avsc")
	if err != nil {
		panic(err)
	}
	codec, err := goavro.NewCodec(schema.String())
	if err != nil {
		panic(err)
	}

	textual, err := json.Marshal(mockUser)
	if err != nil {
		panic(err)
	}

	native, _, err := codec.NativeFromTextual(textual)
	if err != nil {
		panic(err)
	}

	value, err := codec.BinaryFromNative(nil, native)
	if err != nil {
		panic(err)
	}

	fmt.Println(value)
}

and the following schema.avsc file:

{
  "type": "record",
  "name": "User",
  "namespace": "mycompany.avro.types",
  "fields": [
    {
      "name": "id",
      "type": "string"
    },
    {
      "name": "createdAt",
      "type": "string"
    },
    {
      "name": "firstName",
      "type": "string"
    },
    {
      "name": "lastName",
      "type": "string"
    },
    {
      "name": "count",
      "type": "int"
    },
    {
      "name": "phone",
      "type": ["null", {
        "type": "record",
        "name": "Phone",
        "namespace": "mycompany.avro.types",
        "fields": [
          {
            "name": "phoneNumber",
            "type": "string"
          }
        ]
      }]
    }
  ]
}

Of course, that code works, but I feel like I have to much steps to build the binary avro data ...

  • First I need to marshal the data to json.
  • Second I convert my json to native, getting a map[string]interface{}
  • Third I can then convert the native map to binary avro []byte.

But is there any other way (faster one?) to convert my User to that avro binary without using json marshal step ?

Thanks by advance ! :) @karrick

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the encoding flow in main, especially json.Marshal, codec.NativeFromTextual, and codec.BinaryFromNative, alongside schema.avsc. Check the goavro API and existing repository examples or tests for direct struct encoding; done means a documented, supported path from User to Avro binary with equivalent output.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
data-engineering
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.