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的安装window电脑,直接下载后解压,运行可执行文件就可以rpc端口1、需要下载一个最新版的apifox(老版的不支持),创建一个grpc的项目

2、导入你刚刚写的proto文件


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、本案例代码