pablomolnar
pablomolnar

Reputation: 548

JSON and struct composition in Go

I have hierarchical structure similar to this Network -> Serie -> Season -> Episodes. This is a simplified version my real hierarchy is 7 levels deep.

I need to decode/encode these objects with the following JSON:

Network:
{
  id: 1,
  name: 'Fox'
}

Series:
{
   id: 2,
   name: 'The Simpsons',
   network: {
      id: 1,
      name: 'Fox'
   }
}

Season:
{
   id: 3,
   name: 'Season 3',
   network: {
      id: 1,
      name: 'Fox'

   },
   series: {
      id: 2,
      name: 'The Simpsons'
   }
}

Episode:
{
   id: 4,
   name: 'Pilot',
   network: {
      id: 1,
      name: 'Fox'
   },
   series: {
      id: 2,
      name: 'The Simpsons'
   },
   season: {
      id: 3,
      name: 'Season 3'
   }
}

I tried composing my objects like these:

type Base struct {
  ID   string `json:"id"`
  Name string `json:"name"`
}

type Network struct {
  Base
}

type Series struct {
  Network // Flatten out all Network properties (ID + Name)
  Network Base `json:"network"`
}

type Season struct {
  Series  // Flatten out all Series properties (ID + Name + Network)
  Series Base `json:"series"`
}

type Episode struct {
  Season  // Flatten out all Season properties (ID + Name + Network + Series)
  Season Season `json:"season"`
}

Of course it doesn't work due "duplicate field error". In addition the JSON result would be deeply nested. In classic OOP this is fairly easy using normal inheritance, in prototype languages it's also doable (Object.create/Mixins)

Is there an elegant way of do this with golang? I would prefer to keep code DRY.

Upvotes: 1

Views: 3478

Answers (1)

Alex Efimov
Alex Efimov

Reputation: 3703

Why not rename the propriety? But keep the json tags, and go will marshal/unmarshal based on that tag

type Base struct {
    ID   string `json:"id"`
    Name string `json:"name"`
}

type Network struct {
    Base
}

type Series struct {
    Network          // Flatten out all Network properties (ID + Name)
    NetworkBase Base `json:"network"`
}

type Season struct {
    Series          // Flatten out all Series properties (ID + Name + Network)
    SeriesBase Base `json:"series"`
}

type Episode struct {
    Season              // Flatten out all Season properties (ID + Name + Network + Series)
    SeasonBase Base `json:"season"`
}

Upvotes: 3

Related Questions