第五届青训营后端第七天学习笔记| 青训营笔记

79 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 7 天

一、本堂课重点内容:

  • api目录讲解
  • 作用详解
  • 个人小结

本文通过项目来进行案例讲解。

二、api目录讲解

顾名思义,api-gateway是网关层设计,是进行路由分发、鉴权、限流等中间层处理的服务部分,该部分结构如下所示。上文提到,我们的网关是基于Hertz进行开发的,因此结构符合Hertz项目结构。分别包含biz、middlewares、router、主函数以及proto文件,下面将一一进行详解。

├── biz                        # 业务逻辑
│   ├── handler                # 前置处理,RPC 调用,返回结果
│   │   ├── UserCommPb
│   │   ├── userFavoPb
│   │   ├── userInfoPb
│   │   ├── userRelationPb
│   │   └── videoOperatorPb
│   ├── model                  # Hertz 生成 Kitex 调用客户端
│   └── rpcClient              # 单例模式 Client
├── main.go
├── middlewares                # 自定义中间件
│   ├── accessLog.go
│   ├── auth.go
│   └── limit.go
└── router                     # 路由
    └── app.go

三、作用详解

  • proto文件

    • 代码生成器基于protoc文件进行文件生成,一个proto文件代表一个微服务,因为我们的模块是分成四个大模块,因此事四个proto文件,分别是comment、userFavo、userInfo以及VideoOperaor。前置环境需要提前安装,hz代码生成器命令如下所示
    • // new文件结构
      hz new --mod=项目名 --idl=proto或者thrift文件
      
  • biz(业务逻辑部分,本层是通过Hertz代码进行生成的)

    • 如上图所示,分为handler、model、rpcClient部分,区别于自动生成的,本项目结合项目特色进行改造,去掉了生成的router,而改用调用rpc服务的客户端生成。
    • handler:它是与App相对应的接口,因此一般来说,有几个接口,handler的函数一般就有几个。以用户信息模块的登陆接口为例,在handler需要完成格式的输出,将rpc的结构体转化成满足文档接口的要求。
// 用户信息的Login登陆
func LoginMethod(ctx context.Context, c *app.RequestContext) {
   var req LoginReq
   // 1.绑定参数
   err := c.BindAndValidate(&req)
   if err != nil {
      respErr := &userInfoPb.LoginResp{StatusMsg: err.Error(), StatusCode: 1}
      c.JSON(200, respErr)
      return
   }
   // 2.调用rpc
   resp, err := rpcClient.UserInfo.Login(ctx, &userInfoPb.LoginReq{
      UserName: req.UserName,
      Password: req.Password,
   })
   // 3.异常处理
   if err != nil {
      respErr := &userInfoPb.LoginResp{StatusMsg: err.Error(), StatusCode: 1}
      c.JSON(200, respErr)
      return
   }
   // 4.正常返回,将格式转成客户端能解析的json格式
   hlog.Info("resp", resp)
   c.JSON(200, utils.H{
      "status_code": resp.GetStatusCode(),
      "status_msg":  resp.GetStatusMsg(),
      "user_id":     resp.GetUserId(),
      "token":       resp.GetToken()},
   )
   return
}
- model:handler函数的参数结构体,这部分是通过protoc生成的。
- rpcClient:rpc客户端生成,是代码抽象的体现,同时在这里实现服务发现
// rpc客户端生成

func init() {
   // nacos服务发现
   c, err := userinfo.NewClient("userInfoImpl", client.WithResolver(resolver.NewNacosResolver(nacos.Cli)))
   if err != nil {
      panic(err)
   }
   UserInfo = c
}

四、个人小结

本文介绍本次字节项目中个人负责的api-gateway部分

五、引用参考: