如何使用goreq接收复杂的JSON数据?

huangapple go评论116阅读模式
英文:

How to receive complex json with goreq?

问题

我是你的中文翻译助手,以下是你要翻译的内容:

我是Go语言的初学者,我正在尝试调用一个JSON REST API,为此我正在尝试使用goreq请求库。在自述文件中,它给出了以下示例来解码接收到的JSON:

type Item struct {
    Id int
    Name string
}

var item Item

res.Body.FromJsonTo(&item)

我理解这个示例,但我接收到的JSON结构要复杂得多(见下文)。我不确定如何创建一个代表这个复杂结构的struct。我可以在一个struct中编写它吗?还是需要使用bidask数组的映射,另一个用于bidask对象的struct,以及一个用于"vars"对象的struct

难道没有任何自动生成json_to_struct()函数的方法,可以在接收到JSON时动态构建结构体吗(我已经搜索过了,但找不到任何相关内容)?

欢迎提供任何提示!

{
    "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
    }
}
英文:

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
    }
}

答案1

得分: 2

TL;DR

> 我可以用一个结构体来表示吗?

可以。

> 还是需要使用映射来表示买入和卖出数组,以及另一个结构体来表示买入和卖出对象?

是的。

在我开始解释之前,我建议你花更多时间熟悉Go语言的编程方式。这可能是一项繁琐的工作,但非常简单。

详细版本

> 我不确定如何创建一个表示这个复杂结构的结构体。

如果你只是要在程序中表示这个结构,而不涉及JSON,你可以按照相同的方式进行。

让我们先用英语解释一下你在消息中的内容,然后再将其翻译成Go语言:

你有一个包含以下字段的结构体:

  • Success - 布尔类型
  • Message - 字符串类型
  • Result - 结构体类型

现在,Result也是一个结构体,所以我们需要描述它:

  • Bids - 结构体数组
  • Asks - 结构体数组
  • Slip - 整数类型

让我们对Bids和Asks做同样的描述(它们的结构相同,所以我会节省空间):

  • Quantity - 整数类型
  • Price - 浮点数类型
  • Cm - 字符串类型

现在让我们定义我们的结构体:

我们将容器结构体称为"Response",结果结构体称为"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 { 
//由于asks和bids具有相同的结构,我们可以节省代码
  Quantity int `json:"quantity"`
  Price float64 `json:"price"`
  Cm string `json:"cm"`
}

不要忘记添加注释,以便(Un)Marshaling函数可以正确地将JSON字段与结构体字段匹配。

我认为上述方法是实现这个结构的最佳且更易维护的方式,但你也可以将其写成一个结构体,其中包含嵌套的匿名结构体:

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"`
}

顺便说一下,我在几周前发现了一个有趣的工具,可以自动将JSON转换为Go结构体,你可以立即在代码中声明它:https://transform.now.sh/json-to-go/

英文:

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/

huangapple
  • 本文由 发表于 2017年9月19日 16:24:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/46295450.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定