这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天 该篇笔记记录了制作项目的过程。
框架搭建
首先创建IDL文件夹,并补充api的所有结构以及服务。
- 根据官方提供的IDL文档以及接口的类型及请求参数文档,编写一份api的IDL文档。注意service处定义路由以及
message结构体中的api.query等(即Field 注解)要与请求接口说明的类型一致
随后使用Hertz自带的命令行来生成脚手架,主要对于API板块,紧接着编写好服务器的主要Main.go文件
随后写好config,里面记录着常量
随后完成jwt的初始化工作(jwt负责根据token找userid----其仅需要在自动生成的路由里定义好起始即可~!)
至此框架搭建完毕
Git使用说明
将框架拉到本地后,记得先在本地creat一个新的branch,并且在提交代码时,提交到新的branch里,随后完成代码书写后,最后使用push,届时会自动生成多个分支,reviewer会检查PR,决定合并与否。
每次合并之后,记得手动fetch一下代码
service如何插入框架
【注意import的格式】我们默认的根目录为github.com/xiaohei366/TinyTiktok/,在开发过程中,后面直接加相对路径!
以我的user为例:
-
首先写好user的idl文件,对应暴露的接口和服务。随后在cmd文件夹下,创建自己模块的文件夹,并通过定义好的idl文件来自动的生成服务端的微服务框架。
kitex -module github.com/xiaohei366/TinyTiktok -service UserService -I ./../../idl ./../../idl/UserServer.proto- 正常情况下,已生成完整的结构
- 但是为了下次update生成时,需要重复的定义行为,我们将另外在该文件夹下面创建实质的逻辑函数
-
在相应的cmd文件夹下的文件夹内,添加三个文件夹
-
service--处理微服务的运行逻辑,该文件夹下创立两个文件夹,本地直接创建{{servicename.go}}来处理不同的逻辑(注意创建完,需要添加到handler.go文件中)
- dal---处理底层数据库函数
- pack---处理数据库提取后的拼接格式化函数
-
initialize--进行各种初始化的操作
-
config--存放全局常量、配置微服务所需的结构体等...
-
-
先写生成框架的main函数
- 根据初始化,完成数据库的init和全局常量的config的书写以及initialize文件夹下的书写(若需要调用人家的服务,记得也初始化上rpc)
- 随后初始化注册中心并打开服务器
-
随后书写handler.go(因为是自动生成,因此在这里不主动处理逻辑),主要是逻辑外的格式校验与响应返回
- 这里的书写也将意味着需要对service中的pack里面的响应做一个方法的封装(例如,对通用响应体(code+message)的方法封装)
-
这个过程中,因为要书写响应,因此会一步步地完善dal(存放对数据库的操作)、pack(对于handle中响应报文的拼接操作)、service(主要动作逻辑)中的内容。这三部分写完,则代表着整个服务已经完成,但是目前还不可以测试,我们需要完成与主api-server的对接
- 这一步在书写时,可以参考easy-note项目中的note部分,你负责的模块有可能需要用到其他人的函数,这时候自行在模块的根目录(例如我是cmd/user)下创建rpc文件夹书写即可。
- 顺序大概为首先书写dal层、随后写service,最后在pack里写好封装,不全handler即可!
-
首先,在cmd/api/biz/rpc下的创建自己模块的go文件(勿忘在init.go进行注册),并根据cmd/api/biz/handler/ApiServer/api_service.go中你负责的接口结构体的所需的数据选择自己微服务服务器开放的响应接口函数,完成初始化。
- 注意,为了完全解耦,同时保持rpc客户服务端接口的一致性。因此,我们需要将自己模块中的kitex_gen文件夹下的服务文件复制一份到cmd/api/biz/kitex_gen/UserServer。
- 复制时,需要同时修改如下图所示的文件夹下的四个文件的import路径,改至api路径下。
- 初始化工作对照自己模块的handler--书写rpc接口
-
这里插入一小条~,我去搞jwt的初始化去了!
-
去
cmd/api/biz/router/ApiServer/middleware.go中设置JWT中间件,这一步主要是JWT鉴权你的token,并允许你使用token中携带的信息(如何使用看注意事项)- 其各个函数对应的路由中间件,可以对照
cmd/api/biz/router/ApiServer/middleware.go
- 其各个函数对应的路由中间件,可以对照
- ```go
// use jwt mw
mw.JwtMiddleware.MiddlewareFunc()
-
最后去
cmd/api/biz/handler/ApiServer/api_service.go,书写你服务的处理逻辑。- 这里为了方便封装响应报文对应的状态码---特意增加了一个pack.go函数,从里面可以定义你服务的响应报文格式。
注意事项
-
在请求方request的接口中,不需要定义
token字段,因为JWT会帮我们处理好(取而代之的就是设置JWT中间件),可以通过下一条注意事项直接从api服务端获得id传给微服务端,因此若请求只有一个token, 则把他直接换为id即可 -
如何在token中携带信息?如何提取jwt中token中携带的信息
- 首先要像note项目中,在中间件部分加入鉴权
mw.JwtMiddleware.MiddlewareFunc(),,这个函数会将信息自动保存在RequestContext中 cmd/api/biz/middleware/jwt.go中的IdentityHandler以及PayloadFunc负责将信息注入app.RequestContext中。(但是请注意,默认携带的是userId,如想带其他的,可以联系我修改Authenticator函数的返回值,从而带上其他的信息)-
LoginResponse: func(ctx context.Context, c *app.RequestContext, code int, token string, expire time.Time) { v, _ := c.Get(shared.IdentityKey) //取出token中储存的信息 c.JSON(code, utils.H{ "status_code": errno.Success.ErrCode, "status_msg": "success", "user_id": v.(*api.User).Id,//此处演示如何使用 "token": token, }) },
- 首先要像note项目中,在中间件部分加入鉴权
项目启动
Run User RPC Server
cd ./cmd/user/initialize/db
#根据指令需要先配置好对应的数据库--数据库名建议"TinyTiktok"(shared处可修改)
cd ./cmd/user
sh build.sh
sh output/bootstrap.sh
Run API Server
cd ./cmd/api
go run .
创建环境
注意修改自己模块里的config,用户名&密码参考user的设置。
cd ./
docker-compose up -d
此时,当桌面版docker出现该容器后,证明环境初始化成功:
此时,启动几个server即可。