微服务之go-zero:rpc向api通用传值

718 阅读3分钟

微服务之go-zero:rpc向api通用传值

致谢\color{darkred}{致谢}

谨以本文致谢微信群“go-zero社区22”的好朋友溏心荷包煎蛋\color{darkblue}{溏心荷包煎蛋}凉拌西兰花\color{darkblue}{凉拌西兰花},村夫系从二位兄弟处得到本文所述的方法。

写在前面

村夫常谈村夫为什么要使用微服务?\color{darkred}{村夫为什么要使用微服务?}
答曰

单体服务很香,部署时非常方便!但是……  
当我们A系统功能模块需要升级时,OA审批流程中的某一触发任务可能需要使用咱A系统中的其它模块。
当我们发现单体的A系统已经遇到性能瓶颈!

村夫常谈微服务的系统构成框图\color{darkred}{微服务的系统构成框图}
在这样的架构中,当前端发起请求后,实际的数据是由rpc从数据库或是其他业务系统中获取的。rpc将数据打包为一串json数据流交付给api,再由api将数据返回给前端应用。在基于go-zero的框架中,村夫的api通常就是对rpc的一个简单包装,不存在对数据的再处理。因此村夫非常希望能够在api中直接将收到的rpc数据包直接传输给前端,而不再对数据进行拆包再封装。这样做的好处有二:

  1. 提高api性能\color{deeppink}{提高api性能}
  2. 简化api开发\color{deeppink}{简化api开发}

如果您的框架与村夫的完全不一样,比如说,您就没有使用api层,而是直接将rpc丢给了前端的。那么,本文所述及的内容,应该在您那就没有这种需求。如果您有兴趣,至为感谢您读完后面内容!

如果您与村夫一样用了api+rpc的架构,那么本文可能对您有一定的参考价值!

乡野愚者-村夫的老方法

在遇到溏心荷包煎蛋\color{darkblue}{溏心荷包煎蛋}凉拌西兰花\color{darkblue}{凉拌西兰花}二位兄弟时,村夫是干有需求,毫无头绪。实际代码如下:

// user.proto

message UserInfoData {
    int64 Id = 1;
    string Account = 2;
    int64 Type = 3;
    string Name = 4;
    int64 Gender = 5;
    string Mobile = 6;
    string Company= 7;
}

message UserInfoResponse {
    int64 Code = 1;
    UserInfoData Data = 2;
    string Msg = 3;
}
// user.api  

type UserInfoData {
   Id      int64  `json:"id"`
   Account string `json:"account"`
   Type    int64  `json:"type"`
   Name    string `json:"name"`
   Gender  int64  `json:"gender"`
   Mobile  string `json:"mobile"`
   Company string `json:"company"`
}

type UserInfoResponse {
   Code int64        `json:"code"`
   Data UserInfoData `json:"data"`
   Msg  string       `json:"msg"`
}

村夫是老实巴交,分别在api和proto中实现了一遍相关结构体。

其实不是村夫也不想同样的东西写两遍,只是之前不会……

来自溏心荷包煎蛋及凉拌西兰花的通用方法

村夫是一个不时水群的人,当然也不是闲得egg疼地那种水,是愿意经常与大家交流。

当有兄弟姐妹一时遇到问题卡壳了,而这个问题如果恰巧村夫遇到过,也解决了,村夫是会热心地“指点”一下江山的。
当然村夫也会不时地从群里的流水中汲取一些养分,就比如本文的方法,就是群里交流时两位兄弟提及,于是虚心请教了一下。

再次感谢两位兄弟不吝赐教!

下面代码非两位兄弟提供的原始内容,是村夫根据两位兄弟所述方法重建的测试代码!

// kitcat.proto

// Response Data
message RespData {
  string Kit = 1;
  string Cat = 2;
}

// Greet Response
message GreetResp {
  RespStatus Status = 1;
  RespData Data = 2;
}
// kitcat.api

type Resp {
   Status Status     
   Data   interface{}
}

简简单单的interface{},四两拨千斤,胜却人间无数! 妙!

妈妈再也不担心我因为敲键盘而得腱鞘炎了

下面看一下Greet接口的实现:

//greetlogic.go

func (l *GreetLogic) Greet(req *types.Req) (resp *types.Resp, err error) {
   // todo: add your logic here and delete this line
   ret, _ := l.svcCtx.KitCatRpc.Greet(l.ctx, &kitcat.StreamReq{
      Name: req.Name,
   })

   resp.Status = types.Status{
      Code:    200,
      Message: ret.Status.Message,
   }
   resp.Data = &ret.Data
   
   return resp, nil
}

直接把rpc的Data送出去就好,简单粗暴! 但十分好使!

写在后面

再次感谢谢微信群“go-zero社区22”的好朋友溏心荷包煎蛋\color{darkblue}{溏心荷包煎蛋}凉拌西兰花\color{darkblue}{凉拌西兰花}两位兄弟。

同时厚着村夫的老脸,求点赞!
只需要简单的动下小手,点击一下鼠标! 村夫在这里谢过了!