一. 项目初始化
创建项目模板
# 使用默认模板创建项目
kratos new user
# 如在国内环境拉取失败, 可 -r 指定源
kratos new user -r https://gitee.com/go-kratos/kratos-layout.git
cd user
二. 拉取项目依赖
go mod tidy
三. 获取一个纯原生,无添加的代码框架
打开internal/service/service.go,将报红内容删除
四. 连接数据库
安装gorm
# 进入项目目录
cd user
# 安装GORM
go get -u gorm.io/gorm
# 安装GORM的mysql驱动
go get -u gorm.io/driver/mysql
.
使用gorm服务内部目录中的data负责业务数据访问,包含 cache、db 等封装,实现了 biz 的 repo 接口。
我们所有的处理数据逻辑全部写在internal/data
打开/internal/data.go
五.模型定义
自己定义一个用户的数据模型,用于对数据库进行操作。
新建:在/biz目录下创建一个名为user.go的文件
在internal/biz/user.go文件里添加如下内容
为了让GORM知道我们定义了一个数据模型我们需要对internal/data/data.go文件进行修改
到这里,我们就完成了用户数据模型的定义,并且让GORM知道我们定义了这个数据模型
六. repo接口的定义
在repo接口中,我们需要定义一些基础操作数据库修改数据的函数
回到internal/biz/user.go文件,继续敲代码
我们创建一个私有的结构体去实现/biz/user.go中的biz.UserRepo接口
七.编写一个接口
生成proto模板
打开终端,执行以下指令
# 进入"user"项目目录
cd user
# 在"api/user/v1"目录下,生成名为"user"的proto模板
kratos proto add api/user/v1/user.proto
编写 proto 模板
引入google/api/annotations.proto
因为我们只写了用户添加模块,所以保留CreateUser,将生成的user.proto文件中其他接口删除
给CreateUser添加路由,设置访问方法为POST,在添加一个body消息主体
生成proto源码
打开终端,执行以下指令
# 在"api/user/v1"目录下,生成"user"的proto源码
kratos proto client api/user/v1/user.proto
八.生成service模板
在终端中执行下面的命令
kratos proto server api/user/v1/user.proto -t internal/service
我们在用户服务结构体UserService中添加上一节中封装好的用户数据操作biz.UserUseCase。
// UserService 用户服务
type UserService struct {
pb.UnimplementedUserServer
// uc 用户操作的封装,在“/biz/user.go”中
uc *biz.UserUseCase
log *log.Helper
}
修改NewUserService函数的内容,给创建的UserService结构体初始化
func NewUserService(uc *biz.UserUseCase, logger log.Logger) *UserService {
return &UserService{
uc: uc,
log: log.NewHelper(logger),
}
}
编写用户服务中的CreateUser服务接口,使得它能够处理前端发送的请求
// CreateUser 创建用户服务接口
// 这里是一个给前端调用的接口
// 参数中的 req *pb.CreateUserRequest 为前端发送给后端的“创建用户请求参数”
// 如果成功返回一个 *pb.CreateUserReply 它是前端需要得到的回复“创建用户返回结果”
func (s *UserService) CreateUser(ctx context.Context, req *pb.CreateUserRequest) (*pb.CreateUserReply, error) {
// 获取前端发送的Body数据
body := req.GetCreatBody()
// 创建用户
id, err := s.uc.CreateUser(ctx, body.GetName(), body.GetPasswd())
if err != nil {
return nil, err
}
// 给前端返回数据
return &pb.CreateUserReply{
Id: uint64(id),
}, nil
}
按照惯例,让我们吧NewUserService函数添加到依赖提供者集中
修改/service/service.go文件中的wire.NewSet()函数,在NewSet函数里添加NewUserService
// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewUserService)
注册HTTP服务器
在HTTP服务器中注册我们写好的用户服务
打开“/server/http.go”
引入kratos 使用proto生成的源码和我们写好的用户服务
import (
......
user "user/api/user/v1"
"user/internal/service"
)
在“NewHTTPServer”函数的参数中加入我们的用户服务“userService *service.UserService”,以便wire可以正确的注入依赖
// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server, userService *service.UserService, logger log.Logger) *http.Server {
......
}
注册用户服务HTTP服务器
在“NewHTTPServer”函数的末尾加入“user.RegisterUserHTTPServer(srv, userService)”
// NewHTTPServer new a HTTP server.
func NewHTTPServer(c *conf.Server, userService *service.UserService, logger log.Logger) *http.Server {
......
srv := http.NewServer(opts...)
user.RegisterUserHTTPServer(srv, userService)
return srv
}
wire依赖注入
我们“按照惯例”的将所有创建结构体的函数都加入到wire的依赖提供者集中,但这是为啥呢?为什么要将创建结构体的函数都加入到wire的依赖提供者集中呢?
在进行接下来的操作前,请务必确定你的wire依赖提供者集依照上文和前两节中的添加正确
在“/biz/biz.go”中
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewUserUseCase)
在“/data/data.go”中
// ProviderSet is data providers.
var ProviderSet = wire.NewSet(NewData, NewDataBase, NewUseRepo)
在“/service/service.go”中
// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewUserService)
在终端中输入命令
# 进入项目目录
cd user
# 生成所有proto源码、wire等等
go generate ./...
九.测试
根据上面的步骤来到这里,我们的用户添加操作就完成了。接下来我们要对自己写的接口进行测试,看看是否能跑通
在终端中输入命令
# 运行项目
kratos run
评论