一、入门案例
-
1、使用
goland
创建一个工程 -
2、新建一个
user.proto
syntax = "proto3"; package user; // 这个地方表示生成的go的包名叫user option go_package = "./user"; message UserInfoRequest { int64 userId = 1; } message UserInfoResponse { int64 userId = 1; string username = 2; } message UserCreateRequest { string username = 1; string password = 2; } message UserCreateResponse { string message = 1; } // 定义两个方法 service Users { rpc UserInfoById(UserInfoRequest) returns(UserInfoResponse); rpc CreateUser(UserCreateRequest) returns(UserCreateResponse); } // goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.
-
3、使用
goctl
执行生成对应的项目文件goctl rpc protoc user.proto --go_out=./types --go-grpc_out=./types --zrpc_out=.
-
4、安装依赖包
-
5、运行文件
go run user.go
,不出意外的话肯定会启动后挂的,查看etc/user.yaml
文件里面用etcd
的服务,但是本地没启动etcd
二、etcd
的安装
- 1、github下载地址
- 2、如果是
window
电脑,直接下载后解压,运行可执行文件就可以 - 3、可视界面的安装
- 4、具体使用可以自己查看文档
三、测试启动的rpc
端口
-
1、需要下载一个最新版的
apifox
(老版的不支持),创建一个grpc
的项目 -
2、导入你刚刚写的
proto
文件
- 3、测试调用接口
-
4、在
internal/logic/userinfobyidlogic.go
里面补充代码,重启服务继续测试func (l *UserInfoByIdLogic) UserInfoById(in *user.UserInfoRequest) (*user.UserInfoResponse, error) { // todo: add your logic here and delete this line return &user.UserInfoResponse{ UserId: in.UserId, Username: "水痕", }, nil }
四、rpc
对接gorm
数据库操作
-
1、参考
go-zero
对数据库的操作,基本步骤都是一样的,这里就不继续重复的工作 -
2、修改根据用户
id
查询用户数据方法func (l *UserInfoByIdLogic) UserInfoById(in *user.UserInfoRequest) (*user.UserInfoResponse, error) { // todo: add your logic here and delete this line //userEntity := &model.UserEntity{} //l.svcCtx.MySqlDb.Where("id = ?", in.UserId).First(&userEntity) userEntity, err := dao.Use(l.svcCtx.MySqlDb).UserEntity.WithContext(l.ctx).Where(dao.Use(l.svcCtx.MySqlDb).UserEntity.ID.Eq(in.UserId)).First() fmt.Println(userEntity, "获取到的数据") return &user.UserInfoResponse{ UserId: userEntity.ID, Username: userEntity.Username, }, err }
-
3、继续测试下创建用户的方法
func (l *CreateUserLogic) CreateUser(in *user.UserCreateRequest) (*user.UserCreateResponse, error) { // todo: add your logic here and delete this line if err := dao.Use(l.svcCtx.MySqlDb).UserEntity.Create(&model.UserEntity{ Username: in.Username, Password: in.Password, }); err != nil { return &user.UserCreateResponse{ Message: "创建失败", }, nil } return &user.UserCreateResponse{ Message: "创建成功", }, nil }
五、api
对接rpc
接口
-
1、创建一个项目分别创建两个文件夹
rpc
和api
-
2、
rpc
项目和上面介绍的一样的,这里就不继续重复介绍,执行转换脚本goctl rpc protoc user.proto --go_out=types --go-grpc_out=types --zrpc_out=.
-
3、创建一个
user.api
文件type CreateRequest { Username string `json:"username"` Password string `json:"password"` } type CreateResponse { Message string `json:"message"` } type UserInfoRequest { Id int64 `path:"id"` } type UserInfoResponse { Id int64 `json:"id"` Username string `json:"username"` } // 定义要被方法的方法 service users { @handler create post /api/users (CreateRequest) returns (CreateResponse) @handler userInfo get /api/users/:id (UserInfoRequest) returns (UserInfoResponse) }
-
4、在
api/etc/users.yaml
文件中添加rpc
中配置Name: users Host: 0.0.0.0 Port: 8888 # 直接引入etcd的地址就可以,Key直接查看rpc/etc/user.yaml,并且要保持一致 UserRpc: Etcd: Hosts: - 127.0.0.1:2379 Key: user.rpc
-
5、在
api/internal/config/config.go
中添加user.rpc
的配置package config import ( "github.com/zeromicro/go-zero/rest" "github.com/zeromicro/go-zero/zrpc" ) type Config struct { rest.RestConf UserRpc zrpc.RpcClientConf }
-
6、
api/internal/svc/servicecontext.go
添加rpc
的服务配置package svc import ( "github.com/zeromicro/go-zero/zrpc" "zero_demo06_rpc_api/api/internal/config" "zero_demo06_rpc_api/rpc/userclient" ) type ServiceContext struct { Config config.Config UserRpc userclient.User } func NewServiceContext(c config.Config) *ServiceContext { return &ServiceContext{ Config: c, UserRpc: userclient.NewUser(zrpc.MustNewClient(c.UserRpc)), } }
-
7、在
api/internal/logic
里面写业务逻辑func (l *UserInfoLogic) UserInfo(req *types.UserInfoRequest) (resp *types.UserInfoResponse, err error) { // todo: add your logic here and delete this line userInfo, err := l.svcCtx.UserRpc.UserInfoById(l.ctx, &user.UserInfoRequest{UserId: req.Id}) if err != nil { return &types.UserInfoResponse{}, err } return &types.UserInfoResponse{ Id: userInfo.UserId, Username: userInfo.Username, }, nil }
func (l *CreateLogic) Create(req *types.CreateRequest) (resp *types.CreateResponse, err error) { // todo: add your logic here and delete this line createUser, err := l.svcCtx.UserRpc.CreateUser(l.ctx, &user.UserCreateRequest{ Username: req.Username, Password: req.Password, }) if err != nil { return nil, err } return &types.CreateResponse{ Message: createUser.Message, }, nil }
-
8、运行2个项目,前端直接访问
api
层接口 -
9、本案例代码