Search code examples
arraysjsongounmarshallinggo-structtag

JSON Arrays as Go Structs


I am trying to call an array of objects from my JSON file but I am always facing an error saying: "cannot unmarshal array into Go value of type config.APPConfig". How can I ensure the configs how my Go struct calls the array of objects within my JSON file? Here are both my config file in which I set up the Go structs and the JSON file:

Config.go

package config

import (
 "encoding/json"
 "io/ioutil"
)

type Easy struct {
 UID string `json:"uId"`
}

type Auth struct {
 Code string `json:"code"`
}

type APPConfig struct {
 OpenAPIMode string `json:"openAPIMode"` 
 OpenAPIURL  string `json:"openAPIUrl"`  

 ClientID string `json:"clientId"` 
 Secret   string `json:"secret"` 

 AuthMode string `json:"authMode"`

 Easy Easy `json:"easy"`
 Auth Auth `json:"auth"`

 DeviceID string `json:"deviceId"`

 UID          string `json:"-"` 
 MQTTUID      string `json:"-"` 
 AccessToken  string `json:"-"`
 RefreshToken string `json:"-"`
 ExpireTime   int64  `json:"-"`
}

var App = APPConfig{
  OpenAPIMode: "mqtt",
  OpenAPIURL:  "openapi.tuyacn.com",
}


func LoadConfig() error {
  return parseJSON("webrtc.json", &App)
}

func parseJSON(path string, v interface{}) error {
  data, err := ioutil.ReadFile(path)
  if err != nil {
    return err
}

 err = json.Unmarshal(data, v)
 return err
}

JSON file

[
  {
    "openAPIMode": "mqtt",
    "openAPIUrl": "openapi.tuyaus.com",
    "clientId": "*****",
    "secret": "**************",
    "authMode": "easy",
    "easy": {
      "uId": "**********"
    },
    "auth": {
      "code": ""
    },
    "deviceId": "***********"
  },
  {
    "openAPIMode": "mqtt",
    "openAPIUrl": "openapi.tuyaus.com",
    "clientId": "*****",
    "secret": "**************",
    "authMode": "easy",
    "easy": {
      "uId": "**********"
    },
    "auth": {
      "code": ""
    },
    "deviceId": "***********"
  }
]

Thanks in advance for helping!


Solution

  • Your config json file is an Array of JSON and you are parsing it to struct you need to parse it to array of struct.

    To fix your code change the initialization of App to this.

    var App []APPConfig
    
    func LoadConfig() error {
        return parseJSON("webrtc.json", &App)
    }
    

    Here's example full code for it.

    package main
    
    import (
        "encoding/json"
        "fmt"
        "io/ioutil"
    )
    
    type Easy struct {
        UID string `json:"uId"`
    }
    
    type Auth struct {
        Code string `json:"code"`
    }
    
    type APPConfig struct {
        OpenAPIMode string `json:"openAPIMode"`
        OpenAPIURL  string `json:"openAPIUrl"`
    
        ClientID string `json:"clientId"`
        Secret   string `json:"secret"`
    
        AuthMode string `json:"authMode"`
    
        Easy Easy `json:"easy"`
        Auth Auth `json:"auth"`
    
        DeviceID string `json:"deviceId"`
    
        UID          string `json:"-"`
        MQTTUID      string `json:"-"`
        AccessToken  string `json:"-"`
        RefreshToken string `json:"-"`
        ExpireTime   int64  `json:"-"`
    }
    
    var App []APPConfig
    
    func LoadConfig() error {
        return parseJSON("webrtc.json", &App)
    }
    
    func parseJSON(path string, v interface{}) error {
        data, err := ioutil.ReadFile(path)
        if err != nil {
            return err
        }
    
        err = json.Unmarshal(data, v)
        return err
    }
    
    func main() {
        err := LoadConfig()
        if err != nil {
            panic(err)
        }
        fmt.Printf("%+v\n", App)
    }