如何在不解组 JSON 的情况下传递 JSON 响应。

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

Go: How do I pass a JSON response without unmarshalling it

问题

使用Go语言,我正在尝试从多个端点并发地获取几个JSON响应。我想将每个响应附加到结构体或映射中的字段,并将此结构体/映射作为JSON对象返回(前端后端模式)。因此,我将向Go应用程序发出带有某种标识符的Web请求。它将进一步发出多个Web请求,并将数据编译成一个大对象以作为响应返回。

我正在使用Fiber作为我的框架,但任何通用的Web框架都会类似:

  1. app.Get("/requests/:identifier", func(c *fiber.Ctx) error {
  2. identifier := c.Params("identifier")
  3. timeout := 1600 * time.Millisecond
  4. client := httpclient.NewClient(httpclient.WithHTTPTimeout(timeout))
  5. res, err := client.Get("https://www.example.com/endpoint?id=" + identifier, nil)
  6. if err != nil{
  7. logger.Error("Timout value exceeded")
  8. return c.Status(503).SendString("Socket Timeout")
  9. }
  10. logger.Info("Fetch success: ")
  11. // Heimdall returns the standard *http.Response object
  12. body, err := ioutil.ReadAll(res.Body)
  13. code := 200
  14. response := &main_response{
  15. Service1: body,
  16. }
  17. return c.Status(code).JSON(response)
  18. })

我遇到的问题是,我不需要在Go中解组这些数据,因为我对它没有用处(我只是传递它)。我是否必须解组它,以便我可以将其设置为响应结构体中的字段,就像这样?

  1. type main_response struct {
  2. Service1 []byte `json:"service1"`
  3. Service2 map[string]string `json:"service2"`
  4. Service3 map[string]interface{} `json:"service3"`
  5. }

(我尝试了几种不同的方法来实现这一点。尝试使用字节数组似乎会对响应进行Base64编码)

在返回之前,我将想要将该结构体编组为JSON,因此也许我别无选择,因为我想不到一种告诉Go“只编组主结构体,其他一切都已经是JSON”的方法。在这一点上,我几乎觉得最好构建一个字符串。

英文:

Using Go, I'm attempting to fetch a few JSON responses concurrently from multiple endpoints. I'd like to attach each of these responses to fields in a struct or map and return this struct/map as a JSON object. (Backend for Frontend pattern). So I will make a web request to the Go application with some sort of identifier. It will in turn make several web requests, and compile the data into one large object to return as a response.

I'm using Fiber as my framework but any generic web framework would be similar:

  1. app.Get("/requests/:identifier", func(c *fiber.Ctx) error {
  2. identifier := c.Params("identifier")
  3. timeout := 1600 * time.Millisecond
  4. client := httpclient.NewClient(httpclient.WithHTTPTimeout(timeout))
  5. res, err := client.Get("https://www.example.com/endpoint?id=" + identifier, nil)
  6. if err != nil{
  7. logger.Error("Timout value exceeded")
  8. return c.Status(503).SendString("Socket Timeout")
  9. }
  10. logger.Info("Fetch success: ")
  11. // Heimdall returns the standard *http.Response object
  12. body, err := ioutil.ReadAll(res.Body)
  13. code := 200
  14. response := &main_response{
  15. Service1: body,
  16. }
  17. return c.Status(code).JSON(response)
  18. })

The problem I'm having is, I have no need to unmarshal this data in Go, as I have no use for it (I am simply passing it along). Do I have to unmarshal it just so I can set it as a field in my response struct like this?

  1. type main_response struct {
  2. Service1 []byte `json:"service1"`
  3. Service2 map[string]string `json:"service2"`
  4. Service3 map[string]interface{} `json:"service3"`
  5. }

(I've tried a few different ways to accomplish this. Trying to use a byte array seems to base64 encode the responses)

I will want to marshal that struct to JSON before returning it, so perhaps I have little choice as I can't think of a way to tell Go "only marshal the main struct, everything else is already JSON". It almost feels like I'd be better off building a string at this point.

答案1

得分: 4

使用 json.RawMessage 将包含 JSON 的 []byte 直接复制到响应的 JSON 文档中:

  1. type main_response struct {
  2. Service1 json.RawMessage `json:"service1"`
  3. ...
  4. }
  5. response := &main_response{
  6. Service1: body,
  7. }
  8. return c.Status(code).JSON(response)
英文:

Use json.RawMessage to copy a []byte containing JSON directly to the response JSON document:

  1. type main_response struct {
  2. Service1 json.RawMessage `json:"service1"`
  3. ...
  4. }
  5. response := &main_response{
  6. Service1: body,
  7. }
  8. return c.Status(code).JSON(response)

huangapple
  • 本文由 发表于 2022年5月9日 12:54:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/72167141.html
匿名

发表评论

匿名网友

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

确定