AndreaM16 AndreaM16 - 2 months ago 12
JSON Question

Marshall JSON Slice to valid JSON

I'm building a REST API using Golang but I'm having some troubles trying to correctly Marshalling a Json Slice. I've been scratching my head for a while now, even after looking to several questions and answer and on the web.

Essentially, I have a Redis client that called after a call

-X GET /todo/
spits up a slice of
todos


[{"content":"test6","id":"46"} {"content":"test5","id":"45"}] //[]string


Now, I want to return a given
Response
based on the fact that I found
todos
or not, so I have a
Struct
like

type Response struct {
Status string
Data []string
}


Then, If I found some
todos
I just
Marshal
a json with

if(len(todos) > 0){
res := SliceResponse{"Ok", todos}
response, _ = json.Marshal(res)
}


And, In order to remove unnecessary
\
inside the response, I use
bytes.Replace
like

response = bytes.Replace(response, []byte("\\"), []byte(""), -1)


Finally, getting

{
"Status" : "Ok",
"Data" : [
"{"content":"test6","id":"46"}",
"{"content":"test5","id":"45"}"
]
}


As you can see each
"
before each
{
and after each
}
, excluding the first and the last ones, are clearly wrong.
While the correct JSON would be

{
"Status": "Ok",
"Data": [{
"content ": "test6",
"id ": "46"
}, {
"content ": "test5",
"id ": "45"
}]
}



I successfully managed to get them off by finding their index and trim them off and
also with regex but I was wondering.


Is there a clean and better way to achieve that?

Answer

Whenever possible you should marshal from go objects that match your desired json. I'd recommend parsing the json from redis:

type Response struct {
    Status string
    Data   []*Info
}

type Info struct {
    Content string `json:"content"`
    ID      string `json:"id"`
}

func main() {
    r := &Response{Status: "OK"}
    for _, d := range data {
        info := &Info{}
        json.Unmarshal([]byte(d), info)
        //handle error
        r.Data = append(r.Data, info)
    }
    dat, _ := json.Marshal(r)
    fmt.Println(string(dat))
}

Playground Link