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

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

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

问题

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

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

app.Get("/requests/:identifier", func(c *fiber.Ctx) error {
    identifier := c.Params("identifier")
    timeout := 1600 * time.Millisecond
    client := httpclient.NewClient(httpclient.WithHTTPTimeout(timeout))
    res, err := client.Get("https://www.example.com/endpoint?id=" + identifier, nil)

    if err != nil{
        logger.Error("Timout value exceeded")
        return c.Status(503).SendString("Socket Timeout")
    }

    logger.Info("Fetch success: ")

    // Heimdall returns the standard *http.Response object
    body, err := ioutil.ReadAll(res.Body)
    code := 200

    response := &main_response{
        Service1: body,
    }

    return c.Status(code).JSON(response)
})

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

type main_response struct {
    Service1 []byte `json:"service1"`
    Service2 map[string]string `json:"service2"`
    Service3 map[string]interface{} `json:"service3"`
}

(我尝试了几种不同的方法来实现这一点。尝试使用字节数组似乎会对响应进行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:

app.Get("/requests/:identifier", func(c *fiber.Ctx) error {
    identifier := c.Params("identifier")
    timeout := 1600 * time.Millisecond
    client := httpclient.NewClient(httpclient.WithHTTPTimeout(timeout))
    res, err := client.Get("https://www.example.com/endpoint?id=" + identifier, nil)

    if err != nil{
        logger.Error("Timout value exceeded")
        return c.Status(503).SendString("Socket Timeout")
    }

    logger.Info("Fetch success: ")

    // Heimdall returns the standard *http.Response object
    body, err := ioutil.ReadAll(res.Body)
    code := 200

    response := &main_response{
        Service1: body,
    }

    return c.Status(code).JSON(response)
})

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?

type main_response struct {
    Service1 []byte `json:"service1"`
    Service2 map[string]string `json:"service2"`
    Service3 map[string]interface{} `json:"service3"`
}

(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 文档中:

type main_response struct {
    Service1 json.RawMessage `json:"service1"`
    ...
}

response := &main_response{
    Service1: body,
}

return c.Status(code).JSON(response)
英文:

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

type main_response struct {
    Service1 json.RawMessage `json:"service1"`
    ...
}

response := &main_response{
    Service1: body,
}

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:

确定