skip to Main Content

I’m working on a project and it is my first time using Go.

The project queries a number of APIs and for the most part I have had no trouble getting this working.

Coming from a PHP background, creating Go type definitions for my JSON responses is a little different.

I am stuck on one API, a Magento API, that returns a JSON response like so:

{
    "66937": {
        "entity_id": "66937",
        "website_id": "1",
        "email": "[email protected]",
        "group_id": "1",
        "created_at": "2017-08-11 02:09:18",
        "disable_auto_group_change": "0",
        "firstname": "Joe",
        "lastname": "Bloggs",
        "created_in": "New Zealand Store View"
    },
    "66938": {
        "entity_id": "66938",
        "website_id": "1",
        "email": "[email protected]",
        "group_id": "1",
        "created_at": "2017-08-11 02:16:41",
        "disable_auto_group_change": "0",
        "firstname": "Jane",
        "lastname": "Doe",
        "created_in": "New Zealand Store View"
    }
}

I have been using a tool, JSON-to-Go, to help me create the struct types, however it doesn’t look quite right for this style of response:

type AutoGenerated struct {
    Num0 struct {
        EntityID               string `json:"entity_id"`
        WebsiteID              string `json:"website_id"`
        Email                  string `json:"email"`
        GroupID                string `json:"group_id"`
        CreatedAt              string `json:"created_at"`
        DisableAutoGroupChange string `json:"disable_auto_group_change"`
        Firstname              string `json:"firstname"`
        Lastname               string `json:"lastname"`
        CreatedIn              string `json:"created_in"`
    } `json:"0"`
    Num1 struct {
        EntityID               string `json:"entity_id"`
        WebsiteID              string `json:"website_id"`
        Email                  string `json:"email"`
        GroupID                string `json:"group_id"`
        CreatedAt              string `json:"created_at"`
        DisableAutoGroupChange string `json:"disable_auto_group_change"`
        Firstname              string `json:"firstname"`
        Lastname               string `json:"lastname"`
        CreatedIn              string `json:"created_in"`
    } `json:"1"`
}

All I am interested in is the inner JSON – the stuff to actually do with the customer. I am looping over this to extract some information.

How do I create the required struct to read from this?

I have looked at any number of documents or articles but they tend to use more simple JSON responses as examples.

3

Answers


  1. For your JSON structure following might suit well.

    Play Link: https://play.golang.org/p/ygXsdYALCb

    Create a struct called Info or name you prefer also customize your field names as you like.

    type Info struct {
        EntityID               string `json:"entity_id"`
        WebsiteID              string `json:"website_id"`
        Email                  string `json:"email"`
        GroupID                string `json:"group_id"`
        CreatedAt              string `json:"created_at"`
        DisableAutoGroupChange string `json:"disable_auto_group_change"`
        Firstname              string `json:"firstname"`
        Lastname               string `json:"lastname"`
        CreatedIn              string `json:"created_in"`
    }
    

    And create map of Info struct and the unmarshal it.

    var result map[string]Info
    if err := json.Unmarshal(jsonBytes, &result); err != nil {
        fmt.Println(err)
    }
    fmt.Printf("%+v", result)
    

    EDIT:

    As asked in the comment, adding for example:

    fmt.Println("Accessing unmarshal values:")
    for key, info := range result {
        fmt.Println("Key:", key)
        fmt.Printf("Complete Object: %+vn", info)
        fmt.Println("Individual value, typical object field access:")
        fmt.Println("EntityID:", info.EntityID)
        fmt.Println("Email:", info.Email)
    }
    
    Login or Signup to reply.
  2. Well, first, I don’t like the auto-generated struct definitions there. I would change that to look like this

    type Customer struct {
        EntityID               string `json:"entity_id"`
        WebsiteID              string `json:"website_id"`
        Email                  string `json:"email"`
        GroupID                string `json:"group_id"`
        CreatedAt              string `json:"created_at"`
        DisableAutoGroupChange string `json:"disable_auto_group_change"`
        Firstname              string `json:"firstname"`
        Lastname               string `json:"lastname"`
        CreatedIn              string `json:"created_in"`
    }
    

    You may want to create a wrapper type

    type Customers map[string]Customer
    

    This should work with your json that you’ve provided. To put this together

    customers := Customers{}
    err := json.Unmarshal(jsonBytes, &customers)
    
    Login or Signup to reply.
  3. Both @Xibz and @jeevatkm provided great solutions. However, in some cases, not all JSON structures can be unmarshalled into Go structures. You may have to define your own decoding functions.

    You can also try gorilla’s schema package if you have to define your own decoding function for particular data type or structures.

    https://github.com/gorilla/schema

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search