Vivek Singh
Vivek Singh

Reputation: 635

proto3 message type for json marshal data

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

Answers (2)

Victoria Jeffrey
Victoria Jeffrey

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

alecbz
alecbz

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

Related Questions