dongqiao1151 2019-05-08 05:25
浏览 83
已采纳

GRPC消息结构

I am in the process of migrating a legacy application (bit of microservices and monolith) into using GRPC. The entire code base is currently in GO.

I have started to model my messages and they are looking very similar to my structs that I am using in my application code. It seems odd that I have the same objects defined twice but also seems odd to use message objects as core structs. Seems that I will have a lot of memory intensive marshaling of data though. Below is an example of a message and a struct and how similar they are.

Are there any recommendations/best practices on deciding how to model my messages? Should they be aligned with my core structs? Should I not care about all the marshalling that has to happen from my Golang Structs into messages?

Forgive me if I am asking such a basic question as I am very new to protocol buffers and GRPC.

Message Proto Def:

message Profile {
    string UID = 1;
    string ContactEmail = 2;
    google.protobuf.Timestamp DateOfBirth = 3;
    float WeightInKilos = 4;
    string Gender = 5;
    string Unit = 6;
    string CurrentStatus = 7;
    string Country = 8;
    string ExperienceType = 9;
    google.protobuf.Timestamp DateJoined = 10;
    repeated Ability Abilities = 11;
    repeated Role Roles = 12;
    repeated TermsAndConditionsAcceptance TermsAndConditionsAcceptances = 13;
    string TimeZone = 14;
    repeated BaselineTestResults BaselineTests =15;
    //Excluded UpdatedDate as other domains shouldn't need it
    string FirstName =16;
    string LastName =17;
    string DisplayName = 18;
    string State = 19;
    repeated google.protobuf.Any Preferences = 20;
    Thresholds Thresholds = 21;
    string StripeCustomerID = 22;
}

Struct Def:

type Profile struct {
    UID                           string                         `json:"UID" firestore:"UID"`
    ContactEmail                  string                         `json:"ContactEmail,omitempty" firestore:"ContactEmail"`
    DateOfBirth                   time.Time                      `json:"DateOfBirth,omitempty" firestore:"DateOfBirth"`
    WeightInKilos                 float64                        `json:"WeightInKilos,omitempty" firestore:"WeightInKilos"`
    Gender                        string                         `json:"Gender,omitempty" firestore:"Gender"`
    Unit                          string                         `json:"Unit,omitempty" firestore:"Unit"`
    CurrentStatus                 string                         `json:"CurrentStatus,omitempty" firestore:"CurrentStatus"`
    Country                       string                         `json:"Country,omitempty" firestore:"Country"`
    ExperienceType                string                         `json:"ExperienceType,omitempty" firestore:"ExperienceType"`
    DateJoined                    time.Time                      `json:"DateJoined,omitempty" firestore:"DateJoined"`
    Abilities                     []Ability                      `json:"Abilities,omitempty" firestore:"Abilities"`
    Goals                         Goals                          `json:"Goals,omitempty" firestore:"Goals"`
    Roles                         []Role                         `json:"Roles,omitempty" firestore:"Roles"`
    TermsAndConditionsAcceptances []TermsAndConditionsAcceptance `json:"TermsAndConditionsAcceptances,omitempty" firestore:"TermsAndConditionsAcceptances"`
    TimeZone                      string                         `json:"TimeZone,omitempty" firestore:"TimeZone"`
    BaselineTests                 []BaselineTestResults          `json:"BaselineTests,omitempty" firestore:"BaselineTests"`
    UpdatedDate                   time.Time                      `json:"UpdatedDate,omitempty" firestore:"UpdatedDate"`
    FirstName                     *string                        `json:"FirstName,omitempty" firestore:"FirstName"`
    LastName                      string                         `json:"LastName,omitempty" firestore:"LastName"`
    DisplayName                   string                         `json:"DisplayName,omitempty" firestore:"DisplayName"`
    State                         string                         `json:"State"`
    Preferences                   map[string]interface{}         `json:"Preferences"`
    Thresholds                    Thresholds                     `json:"Thresholds"`
    StripeCustomerID              string                         `json:"-"` //Tells it to ignore exporting
}
  • 写回答

2条回答 默认 最新

  • dongrenshi0889 2019-05-08 07:30
    关注

    Though a very basic question but a very good question too. People generally skip it and have to struggle with codebase later as it grows.

    Of course using message as core structs will be helpful in cases where the data you need to process the request is completely available in message. But in cases where you need to fetch data from other sources will not be helpful.

    Normally a message data is dealt by boundary-layer/controller which further uses multiple services to create a response. So a service-layer/logic-layer is independent of a controller layer and the same should happen with message structs and core structs.

    Always try to reduce coupling between layers so that they become reusable.

    So if you have a layer which deals with database, you should have separate structs for that too.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度