如何使用goreq接收复杂的json?

I'm a beginner in Go and I'm trying to call a json rest-API for which I'm trying to use the goreq request lib. In the readme it gives the following example for decoding the received json:

type Item struct {
    Id int
    Name string
}

var item Item

res.Body.FromJsonTo(&item)

I understand this example, but the json I'm receiving is way more complex (see below). I'm not sure how I would create a struct which represents this complex structure. Can I write it in one struct, or do I need to use maps for the bid and ask arrays, another struct for the bid and ask objects, and yet one more struct for the "vars" object?

Isn't there any automagic json_to_struct() function which dynamically builds the struct upon receiving the json (I've looked but I can't find anything)?

All tips are welcome!

{
    "success": true,
    "message": "something",
    "vars": {"some": "value", "thenumber": 7612.32},
    "result": {
        "bids": [
            {"quantity": 2, "price": 416.02, "cm": "some text"},
            etc..
        ],
        "asks": [
            {"quantity": 1, "price": 420.02, "cm": "some text"},
            etc..
        ],
        "slip": 4
    }
}

TL;DR

Can I write it in one struct

Yes

or do I need to use maps for the bid and ask arrays, and yet another struct for the bid and ask objects?

Yes

Before I actually do the hand holding here, I'm gonna recommend that you actually spend some more time getting used to the way things are done in Go. This might be tedious work but it is very simple.

Long Version

I'm not sure how I would create a struct which represents this complex structure.

You are going to do it the same way if you just had to represent this in your program, without any JSON.

Let's explain what you have in that message in English before we translate it to Go:

You have a struct with the fields:

  • Success - Boolean
  • Message - String
  • Result - Struct

Now, Result is also a struct, so we need to describe it:

  • Bids - Array of Struct
  • Asks - Array of Struct
  • Slip - Integer

Let's do the same for Bids and Asks (the look the same so I'll save space)

  • Quantity - Integer
  • Price - Float64
  • Cm - String

Now let's define our struct:

Let's call the container struct "Response" and the result one "Result"

type Response struct {
  Success bool `json:"success"`
  Message string `json:"message"`
  Result  Result `json:"result"`
}

type Result struct {
  Bids []Quote `json:"bids"`
  Asks []Quote `json:"asks"`
  Slip int `json:"slip"`
}

type Quote struct { 
//As asks and bids are have the same structure we can save code
  Quantity int `json:"quantity"`
  Price float64 `json:"price"`
  Cm string `json:"cm"`
}

Don't forget to add annotations so that the (Un)Marshaling functions can properly match fields in JSON to the Struct.

I believe the above is the best and more maintainable way of implementing this, however you can also write the same as one struct with nested anonymous structs:

type Response struct {
    Success bool   `json:"success"`
    Message string `json:"message"`
    Result  struct {
        Bids []struct {
            Quantity int     `json:"quantity"`
            Price    float64 `json:"price"`
            Cm       string  `json:"cm"`
        } `json:"bids"`
        Asks []struct {
            Quantity int     `json:"quantity"`
            Price    float64 `json:"price"`
            Cm       string  `json:"cm"`
        } `json:"asks"`
        Slip int `json:"slip"`
    } `json:"result"`
}

By the way, there's an interesting tool that I found a few weeks ago that automatically transforms JSON to a Go struct that you can declare in your code right away: https://transform.now.sh/json-to-go/