2

I'm building microservices app with go and beego. I'm trying to pass JSON response from service A to service B as following:

func (u *ServiceController) GetAll() {
    req := httplib.Get("http://localhost/api/1/services")
    str, err := req.String()
    // str = {"id":1, "name":"some service"}
    if err != nil {
        fmt.Println(err)
    }
    u.Data["json"] = str
    u.ServeJSON()
}

However, when I send the response I actually double json encoding:

"{\"id\":\"1\",\"name\":\"some service\"}"

Finally, this is the solution I came up with:

func (u *ServiceController) GetAll() {
    req := httplib.Get("http://localhost/api/1/services")
    str, err := req.String()
    if err != nil {
        fmt.Println(err)
    }

    strToByte := []byte(str)
    u.Ctx.Output.Header("Content-Type", "application/json")
    u.Ctx.Output.Body(strToByte)
}
wizard
  • 583
  • 2
  • 9
  • 26
  • https://beego.me/docs/mvc/controller/jsonxml.md – mkopriva Dec 10 '17 at 13:48
  • I want to parse the json dynamically. – wizard Dec 10 '17 at 14:12
  • As stated in the link `ServeJSON` "JSONifies" what you set as the value of `Data["json"]`, that means that a string gets turned into valid json string, regardless of the content of the string, that's why its escaped. `ServeJSON` is not meant to be used with strings containing json. – mkopriva Dec 10 '17 at 14:21
  • 1
    If you want to send strings containing valid json you can use `u.Ctx.Output.Body(bytes []byte)`, use `[]byte(str)` to convert your string into bytes. You'll need to also set the HTTP header Content-Type, which you can do like this: `u.Ctx.Output.Header("Content-Type", "application/json")`. – mkopriva Dec 10 '17 at 14:25
  • In JS I would parse to JSON to JS object beforehand, so what should I do in go? – wizard Dec 10 '17 at 14:28
  • `ServeJSON` does that for you, so it expects a value that can be turned into json (e.g. a struct that has exported fields and the proper field tags), just like in the example where they pass `mystruct`, that value gets turned into a json object. – mkopriva Dec 10 '17 at 14:32
  • @mkopriva tnx! I updated your solution in my question. You can post the second solution with `mystruct` here. – wizard Dec 10 '17 at 15:22

1 Answers1

0

Try this:

func (u *ServiceController) GetAll() {
    req := httplib.Get("http://localhost/api/1/services")
    str, err := req.Bytes()
    // str = {"id":1, "name":"some service"}
    if err != nil {
        fmt.Println(err)
    }
    u.Ctx.Output.Header("Content-Type", "text/plain;charset=UTF-8")
    u.Ctx.ResponseWriter.Write(str)
}

If you call req.String(), it will encode the " in the json string. I suggest you use []byte to handle data usually.

Bryce
  • 3,046
  • 2
  • 19
  • 25