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

Time:05-09

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.

CodePudding user 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)
  • Related