avro icon indicating copy to clipboard operation
avro copied to clipboard

Support anonymous struct fields

Open sneko opened this issue 4 years ago • 5 comments

Solves issue #40

Testing

About testing, I tried with this original Go file:

package avro

type Age struct {
	Years   string  `json:"years"`
	Address Address `json:"address"`
}

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

type BaseEvent struct {
	Age
	Address
	EventID string `json:"eventId"`
}

type Person struct {
	BaseEvent
	Firstname string  `json:"firstname"`
	Lastname  string  `json:"lastname"`
	Address   Address `json:"address"`
}

And the command:

go run ./cmd/go2avro/main.go Person

It gives me this result:

{
    "fields": [
        {
            "default": "",
            "name": "years",
            "type": "string"
        },
        {
            "default": {
                "street": ""
            },
            "name": "address",
            "type": {
                "fields": [
                    {
                        "default": "",
                        "name": "street",
                        "type": "string"
                    }
                ],
                "name": "Address",
                "type": "record"
            }
        },
        {
            "default": "",
            "name": "street",
            "type": "string"
        },
        {
            "default": "",
            "name": "eventId",
            "type": "string"
        },
        {
            "default": "",
            "name": "firstname",
            "type": "string"
        },
        {
            "default": "",
            "name": "lastname",
            "type": "string"
        },
        {
            "default": {
                "street": ""
            },
            "name": "address",
            "type": "Address"
        }
    ],
    "name": "Person",
    "type": "record"
}

And if then I use the avrogo to see if it parses correctly, I indeed end up with this final structure:

go run ./cmd/avrogo -p abc def.avsc
type Address struct {
	Street string `json:"street"`
}

type Person struct {
	Years     string  `json:"years"`
	Address   Address `json:"address"`
	Street    string  `json:"street"`
	EventId   string  `json:"eventId"`
	Firstname string  `json:"firstname"`
	Lastname  string  `json:"lastname"`
	Address   Address `json:"address"`
}

Improvements

I took a look at your tests but to be honest not totally confident about how to implement this with yours. Feel free to add those 👍

Thank you,

sneko avatar Aug 01 '20 15:08 sneko

Oups, it seems "address" property has been added 2 times even with my condition. Sorry, will push a fix commit.

The fact is my example stands with a weird Person structure since multiple Anonymous structs that targets "Address" property, but better to fix that just in case ^^

sneko avatar Aug 01 '20 15:08 sneko

Second commit solves the previous issue.

I correctly get the following after Go -> Avro -> Go:

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

type Person struct {
	Years     string  `json:"years"`
	Address   Address `json:"address"`
	Street    string  `json:"street"`
	EventId   string  `json:"eventId"`
	Firstname string  `json:"firstname"`
	Lastname  string  `json:"lastname"`
}

By the way, in case the property Address was added by multiples anonymous structs, or also the Person struct, the new commit will check if same type, and if not, it fails.

sneko avatar Aug 01 '20 15:08 sneko

Note that all tests within your Go module was working well, but it does not when trying to compile my own executable and then try into another Go module directory.

I was always having:

go2avro: cannot get Avro type: cannot get type: anonymous fields not yet supported (in event.Person)

And I just figured out I had to use this replacement:

replace github.com/heetch/avro => ../../../tests/avro

into my other directories because you use a temporary generated Go file that will by default use your package.

I don't know if you had an easier way to develop locally. Hope this tip will help others. In the meantime, I hope this will be merged to avoid dealing with the replace statement everywhere I want to use the modification.

sneko avatar Aug 01 '20 17:08 sneko

@rogpeppe @sixstone-qq , any chance this to be reviewed?

(I know that's holidays, but just asking 😃 , thank you)

sneko avatar Aug 06 '20 08:08 sneko

Update: I definitely move to Protobuf codec for Kafka, too many complications within the Avro ecosystem from my point of view 😞

sneko avatar Dec 02 '20 17:12 sneko