开发流程
- goctl环境准备
- 数据库设计
- 业务开发
- 新建工程
- 创建服务目录
- 创建服务类型(api/rpc/rmq/job/script)
- 编写api、proto文件
- 代码生成
- 生成数据库访问层代码model
- 配置config,yaml变更
- 资源依赖填充(ServiceContext)
- 添加中间件
- 业务代码填充
- 错误处理
goctl环境准备
概述
goctl 是 go-zero 的内置脚手架,是提升开发效率的一大利器,可以一键生成代码、文档、部署 k8s yaml、dockerfile 等
参考官网安装go-zero.dev/docs/tasks/…
数据库设计
创建数据库,把业务表设计好,导入数据库
例如:user.sql
业务开发
新建工程
- 创建目录,go-zero-looklook
- 进入目录,初始化 go mod init go-zero-looklook
创建服务目录
参考www.w3cschool.cn/gozero/goze…
常见服务类型的目录结构
- 每个系统在对外(http)提供服务的同时,也会提供数据给其他子系统进行数据访问的接口(rpc),因此每个子系统可以拆分成一个服务,而且对外提供了两种访问该系统的方式api和rpc
- 除此之外,一个服务下还可能有其他更多服务类型,如rmq(消息处理系统),cron(定时任务系统),script(脚本)等, 因此一个服务下可能包含以下目录结构
完整工程目录结构示例
编写api、proto文件
编写api文件
我们在写api服务代码的时候是先要在usercenter.api中定义好service中的方法,然后在desc/user中写request、response,这样拆分开的好处是不那么臃肿
usercenter.api 中定义注册方法
syntax = "v1"
info(
title: "用户中心服务"
desc: "用户中心服务"
author: "Mikael"
email: "13247629622@163.com"
version: "v1"
)
import (
"user/user.api"
)
//============================> usercenter v1 <============================
//no need login
@server(
prefix: usercenter/v1
group: user
)
service usercenter {
@doc "register"
@handler register
post /user/register (RegisterReq) returns (RegisterResp)
@doc "login"
@handler login
post /user/login (LoginReq) returns (LoginResp)
}
//need login
@server(
prefix: usercenter/v1
group: user
jwt: JwtAuth
)
service usercenter {
@doc "get user info"
@handler detail
post /user/detail (UserInfoReq) returns (UserInfoResp)
@doc "wechat mini auth"
@handler wxMiniAuth
post /user/wxMiniAuth (WXMiniAuthReq) returns (WXMiniAuthResp)
}
user/user.api 中定义RegisterReq\RegisterResp
syntax = "v1"
info(
title: "用户实例"
desc: "用户实例"
author: "Mikael"
email: "13247629622@163.com"
)
type User {
Id int64 `json:"id"`
Mobile string `json:"mobile"`
Nickname string `json:"nickname"`
Sex int64 `json:"sex"`
Avatar string `json:"avatar"`
Info string `json:"info"`
}
type (
RegisterReq {
Mobile string `json:"mobile"`
Password string `json:"password"`
}
RegisterResp {
AccessToken string `json:"accessToken"`
AccessExpire int64 `json:"accessExpire"`
RefreshAfter int64 `json:"refreshAfter"`
}
)
type (
LoginReq {
Mobile string `json:"mobile"`
Password string `json:"password"`
}
LoginResp {
AccessToken string `json:"accessToken"`
AccessExpire int64 `json:"accessExpire"`
RefreshAfter int64 `json:"refreshAfter"`
}
)
type (
WXMiniAuthReq {
Code string `json:"code"`
IV string `json:"iv"`
EncryptedData string `json:"encryptedData"`
}
WXMiniAuthResp {
AccessToken string `json:"accessToken"`
AccessExpire int64 `json:"accessExpire"`
RefreshAfter int64 `json:"refreshAfter"`
}
)
type (
UserInfoReq {
}
UserInfoResp {
UserInfo User `json:"userInfo"`
}
)
代码生成
api规则参考go-zero.dev/docs/tutori…
rpc规则参考go-zero.dev/docs/tutori…
goctl生成api代码
命令行进入service/user/api/desc目录下。执行
goctl api go -api *.api -dir ../
goctl生成rpc代码
命令行进入service/user/rpc/bp目录下。执行
goctl rpc protoc *.proto --go_out=../ --go-grpc_out=../
生成数据库访问层代码model
配置config,yaml变更&资源依赖填充(ServiceContext)
api配置RPC
参考-添加yaml配置(通过etcd连) www.w3cschool.cn/gozero/goze…
api配置RPC直接
- 添加yaml配置,service/user/api/etc/config.yaml
Name: user
Host: 0.0.0.0
Port: 8888
#rpc service 直连配置
UserRpcConf:
Endpoints:
- 127.0.0.1:2004
NonBlock: true
- 添加user rpc配置,service/user/api/internal/config/config.go
type Config struct {
rest.RestConf
UserRpcConf zrpc.RpcClientConf //RPC配置
}
- 完善服务依赖,service/user/api/internal/svc/servicecontext.go
type ServiceContext struct {
Config config.Config
UserRpc user.UserZrpcClient //RPC配置
}
func NewServiceContext(c config.Config) *ServiceContext {
return &ServiceContext{
Config: c,
UserRpc: user.NewUserZrpcClient(zrpc.MustNewClient(c.UserRpcConf)), //RPC配置
}
}
- 业务逻辑调用
l.svcCtx.UserRpc.GetUser(l.ctx, &user.IdRequest{
Id: "1",
})
api配置jtw
- 添加yaml配置,service/user/api/etc/config.yaml
Name: user
Host: 0.0.0.0
Port: 8888
#jwtAuth
JwtAuth:
AccessSecret: ae0536f9-6450-4606-8e13-5a19ed505da0
AccessExpire: 7200
#rpc service 直连配置
UserRpcConf:
Endpoints:
- 127.0.0.1:2004
NonBlock: true
- 添加user rpc配置,service/user/api/internal/config/config.go
type Config struct {
rest.RestConf
JwtAuth struct { // jwt鉴权配置
AccessSecret string // jwt密钥
AccessExpire int64 // 有效期,单位:秒
}
UserRpcConf zrpc.RpcClientConf //RPC配置
}
- 业务逻辑调用
l.svcCtx.Config.JwtAuth.AccessSecret
添加中间件
在go-zero中,中间件可以分为路由中间件和全局中间件,路由中间件是指某一些特定路由需要实现中间件逻辑,其和jwt类似,没有放在jwt:xxx下的路由不会使用中间件功能, 而全局中间件的服务范围则是整个服务。
参考1:s://www.w3cschool.cn/gozero/gozero-alqu3nnc.html
业务代码填充
在前面我们已经根据user.api和usr.pb生成了对应的api和RPC代码,我们只需要填充对应的业务逻辑即可。
api注册逻辑填充
service/user/api/internal/logic/user/registerlogic.go
rpc注册逻辑填充
service/user/rpc/internal/logic/registerlogic.go