为了账号安全,请及时绑定邮箱和手机立即绑定

将 ptypes/struct 值转换为 BSON

将 ptypes/struct 值转换为 BSON

Go
德玛西亚99 2022-05-18 16:42:17
要求两项服务:服务器- 用于向 MongoDB 写博客文章客户端- 向第一个服务发送请求博客文章title的类型为string,并且content是动态类型 - 可以是任何 JSON 值。原型缓冲区syntax = "proto3";package blog;option go_package = "blogpb";import "google/protobuf/struct.proto";message Blog {  string id = 1;  string title = 2;  google.protobuf.Value content = 3;}message CreateBlogRequest {  Blog blog = 1;}message CreateBlogResponse {  Blog blog = 1;}service BlogService {  rpc CreateBlog (CreateBlogRequest) returns (CreateBlogResponse);}让我们从 protobuf 消息开始,它满足要求 - stringfortitle和任何 JSON 值content。客户package mainimport (...)func main() {    cc, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())    defer cc.Close()    c := blogpb.NewBlogServiceClient(cc)    var blog blogpb.Blog    json.Unmarshal([]byte(`{"title": "First example", "content": "string"}`), &blog)    c.CreateBlog(context.Background(), &blogpb.CreateBlogRequest{Blog: &blog})    json.Unmarshal([]byte(`{"title": "Second example", "content": {"foo": "bar"}}`), &blog)    c.CreateBlog(context.Background(), &blogpb.CreateBlogRequest{Blog: &blog})}客户端向服务器发送两个请求 - 一个content具有string类型,另一个具有object. 这里没有错误。
查看完整描述

1 回答

?
aluckdog

TA贡献1847条经验 获得超7个赞

因此,正如@nguyenhoai890 在评论中所建议的那样,我设法使用jsonpblib 修复它 - 首先转换为MarshalToStringBSON支持的structpb转换string(json),然后json.Unmarshal转换string(json)为interface{}BSON 支持的转换。我还必须修复一个客户端以正确地从字符串解组到 protobuf。


客户

func main() {

    cc, _ := grpc.Dial("localhost:50051", grpc.WithInsecure())

    defer cc.Close()

    c := blogpb.NewBlogServiceClient(cc)


    var blog blogpb.Blog

    jsonpb.UnmarshalString(`{"title": "Second example", "content": {"foo": "bar"}}`, &blog)

    c.CreateBlog(context.Background(), &blogpb.CreateBlogRequest{Blog: &blog})


    jsonpb.UnmarshalString(`{"title": "Second example", "content": "stirngas"}`, &blog)

    c.CreateBlog(context.Background(), &blogpb.CreateBlogRequest{Blog: &blog})

}

服务器

type blogItem struct {

    ID      primitive.ObjectID `bson:"_id,omitempty"`

    Title   string             `bson:"title"`

    Content interface{}        `bson:"content"`

}


func (*server) CreateBlog(ctx context.Context, req *blogpb.CreateBlogRequest) (*blogpb.CreateBlogResponse, error) {

    blog := req.GetBlog()


    contentString, err := new(jsonpb.Marshaler).MarshalToString(blog.GetContent())

    if err != nil {

        log.Fatal(err)

    }


    var contentInterface interface{}

    json.Unmarshal([]byte(contentString), &contentInterface)


    data := blogItem{

        Title:   blog.GetTitle(),

        Content: contentInterface,

    }


    res, err := collection.InsertOne(context.Background(), data)

    if err != nil {

        log.Fatal(err)

    }

    oid, _ := res.InsertedID.(primitive.ObjectID)


    return &blogpb.CreateBlogResponse{

        Blog: &blogpb.Blog{

            Id:      oid.Hex(),

            Title:   blog.GetTitle(),

            Content: blog.GetContent(),

        },

    }, nil


}


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 127 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号