0

我正在实现一个 gRPC API,并希望添加 JSON 正文数据作为响应。

所以我试过:

type Message struct {
    Subject string `json:"subject"`
    Body    interface{}  `json:"body"`
}

原型3

message Message {
    string subject = 1;
    string body = 2;
}

接口代码:

    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

添加此获取 gRPC API 响应后:

{
  "subject": "dev",
  "body": "{\"name\":\"environment\",\"description\":\"The default environment\"}",
}

问题是正文 JSON 键值是动态的。有什么方法可以让我们得到类似的回应

{
  "subject": "dev",
  "body": {"name":"environment","description":"The default environment"},
}

4

2 回答 2

1

试试这个:去 go 游乐场(https://play.golang.org/),然后把它放进去:

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)


}

我们正在做的是解组编组的响应,然后使用 strconv unquote 来获取我们想要的字符串

于 2020-03-11T23:43:45.407 回答
1

如果您想要默认的 proto-to-JSON 转换,我认为不可能像这样使用协议缓冲区将真正的任意对象嵌入到有效负载中。

您可以注入自己的逻辑来转换为 JSON 并让它按照您的期望进行。

根据您更广泛的目标,Any s 也可能有用。


注意json这里的标签:

type Message struct {
    Subject string `json:"subject"`
    Body    interface{}  `json:"body"`
}

不相关。gRPC 正在根据协议缓冲区类型生成 JSON Message;这里的标签只影响 Go json 库如何呈现Go类型Message

于 2020-03-12T00:01:20.967 回答