猿问

将 ptypes/struct 值转换为 BSON

要求

两项服务:

  • 服务器- 用于向 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 main


import (...)


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. 这里没有错误。



德玛西亚99
浏览 128回答 1
1回答

aluckdog

因此,正如@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}
随时随地看视频慕课网APP

相关分类

Go
我要回答