Reputation: 635
I am implementing a gRPC API and wanted to add JSON body data as it is in response.
so I have tried:
type Message struct {
Subject string `json:"subject"`
Body interface{} `json:"body"`
}
proto3
message Message {
string subject = 1;
string body = 2;
}
API code:
en, err := client.Request.Get(req.Name)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
data, _ := json.Marshal(en.Body)
return &response.Message{
Subject: en.Subject,
Body: string(data),
}, nil
After adding this getting gRPC API response:
{
"subject": "dev",
"body": "{\"name\":\"environment\",\"description\":\"The default environment\"}",
}
The problem is body JSON key-value is dynamic. Is there any way by which we can get response something like
{
"subject": "dev",
"body": {"name":"environment","description":"The default environment"},
}
Upvotes: 0
Views: 2218
Reputation: 23
try this: go to the go playground (https://play.golang.org/) and then put this in:
package main
import (
"fmt"
"encoding/json"
"strconv"
)
func main() {
b := []byte(`"{\"name\":\"environment\",\"description\":\"The default environment\"}"`)
fmt.Println(string(b))
var msg string
json.Unmarshal([]byte(b), &msg)
smsg, _ := strconv.Unquote(string(b))
fmt.Println(smsg)
}
what we're doing is unmarshalling the marshalled response and then using strconv unquote to get the string we want
Upvotes: 1
Reputation: 6498
I don't think it's possible to embed a truly arbitrary object into the payload like this with protocol buffers, if you want the default proto-to-JSON conversion.
You could inject your own logic to do the conversion to JSON and have it do what you're expecting.
Depending on what your broader goal is, Anys might also be useful.
Note that the json
tags here:
type Message struct {
Subject string `json:"subject"`
Body interface{} `json:"body"`
}
are not relevant. gRPC is generating the JSON based on the protocol buffer type Message
; the tags here only affect how the Go json library will render the Go type Message
.
Upvotes: 1