How to add map into the same struct which is used to deserialize json configs?

Issue

I am working on deserializing json into a struct as shown below and it works fine.

type DataConfigs struct {
    ClientMetrics []Client `json:"ClientMetrics"`
}

type Client struct {
    ClientId  int  `json:"clientId"`
    .....
    .....
}

const (
    ConfigFile = "clientMap.json"
)

func ReadConfig(path string) (*DataConfigs, error) {
    files, err := utilities.FindFiles(path, ConfigFile)
  // check for error here
  
    var dataConfig DataConfigs
    body, err := ioutil.ReadFile(files[0])
  // check for error here
    err = json.Unmarshal(body, &dataConfig)
  // check for error here

    return &dataConfig, nil
}

Now I am trying to build a map of integer and Client using DataConfigs object that was created as shown above in the code. So I created a method to do the job as shown below and I modified ReadConfig method to do that too.

func ReadConfig(path string, logger log.Logger) (*DataConfigs, error) {
  files, err := utilities.FindFiles(path, ConfigFile)
  // check for error here
  
  var dataConfig DataConfigs
  body, err := ioutil.ReadFile(files[0])
  // check for error here
  err = json.Unmarshal(body, &dataConfig)
  // check for error here

  idx := BuildIndex(dataConfig)
  // now how to add this idx and dataConfig object in one struct?
  
  return &dataConfig, nil
}

func BuildIndex(dataConfig DataConfigs) map[int]Client {
    m := make(map[int]Client)
    for _, dataConfig := range dataConfig.ClientMetrics {
        m[dataConfig.ClientId] = dataConfig
    }
    return m
}

My confusion is – Should I modify DataConfigs struct to add idx map too and then return that struct from ReadConfig method or should I create a new struct to handle that?

Basically I want to return DataConfigs struct which has ClientMetrics array along with idx map. How can I do this here? I am slightly confuse because I started with golang recently.

Solution

This is basically a design question with multiple options. First, I would avoid adding the map to your original DataConfigs type since it does not match the json representation. This could lead to confusion down the road.

Which option to choose depends on your requirements and preferences. Some ideas from the top of my head:

  1. Have you considered returning the map only? After all, you’ve got every Client in your map. If you need to iterate all Clients you can iterate all values of your map.
  2. Second option is to return the map in addition to DataConfigs. Go allows to return multiple values from a function as you already do for error handling.
  3. Finally, you could wrap DataConfigs and your map in a new simple struct type as you already guessed.

Answered By – Bastis Programming Corner

Answer Checked By – Dawn Plyler (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.