目录
在本次课程中,我们对 GO-ZERO 基础部分进行了全面的回顾,重点探讨了 API 与 RPC 服务的结合,这是构建完整微服务架构的关键环节。以下是详细的步骤总结以及相关代码示例(部分代码逻辑需根据实际情况进一步完善)。
一、API 与 RPC 服务结合步骤
(一)API 层配置文件操作
- 配置 RPC 服务键(K)
- 在 API 层的配置文件(假设为
user.yaml)中,需要填写 RPC 服务的键(K)。虽然示例中未给出具体地址,但实际应用中需要准确配置 RPC 服务的地址等相关信息,以便 API 层能够正确连接到 RPC 服务。例如:
- 在 API 层的配置文件(假设为
rpcService:
key: userrpc # 这里的userrpc是RPC服务的键,实际需与RPC服务配置对应
(二)依赖注入与初始化 RPC 客户端
- 获取配置与依赖注入
- 在 API 服务的启动过程中,通过相应的配置获取函数(如
cf函数,实际可能是自定义的配置获取逻辑)获取配置信息。然后进行依赖注入,初始化 RPC 客户端。假设使用 GO-ZERO 框架的zrpc包来创建 RPC 客户端,代码示例如下(以下代码可能在main.go或相关服务初始化文件中):
- 在 API 服务的启动过程中,通过相应的配置获取函数(如
package main
import (
"github.com/zeromicro/go-zero/zrpc"
"rpc_api_demo/api/internal/config" // 假设配置文件在config目录下,根据实际情况调整
)
func main() {
var c config.Config
// 加载配置文件(假设配置文件加载逻辑已实现)
conf.MustLoad("etc/user.yaml", &c)
// 创建RPC客户端连接
rpcClient := zrpc.MustNewClient(zrpc.RpcClientConf{
Endpoints: []string{c.RpcService.Key}, // 使用配置文件中的RPC服务键来确定连接地址
})
// 这里可以将rpcClient传递给后续需要使用的地方,例如依赖注入到服务结构体中
}
(三)编写 API 文件并转换
- 编写 API 文件(user.api)
- 在 API 目录下创建
user.api文件,定义 API 接口。例如,创建获取用户信息接口和创建用户接口,如下所示:
- 在 API 目录下创建
// 获取用户信息接口
// @Summary 获取用户信息
// @Description 根据用户ID获取用户详细信息
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param id path int true "用户ID"
// @Success 200 {object} types.UserInfoResponse "获取用户信息成功"
// @Router /user/{id} [get]
// 创建用户接口
// @Summary 创建用户
// @Description 创建新用户
// @Tags 用户管理
// @Accept json
// @Produce json
// @Param user body types.CreateUserRequest true "用户信息"
// @Success 200 {object} types.CreateUserResponse "创建用户成功"
// @Router /user [post]
- 转换 API 文件
- 在终端中,进入 API 目录,执行以下命令将
user.api文件转换为对应的 GO 代码:
- 在终端中,进入 API 目录,执行以下命令将
goctl api go -api user.api -dir.
(四)编写 API 逻辑并调用 RPC 服务
- 创建用户逻辑(createuserlogic.go)
- 在
api/user/logic/createuserlogic.go文件中编写创建用户的逻辑。首先创建 RPC 服务客户端连接(如上述依赖注入部分已完成连接创建),然后调用 RPC 服务的CreateUser方法。假设 RPC 服务的CreateUser方法接收一个CreateUserRequest类型的参数并返回CreateUserResponse类型的结果,代码示例如下:
- 在
package logic
import (
"context"
"rpc_api_demo/api/internal/svc"
"rpc_api_demo/api/internal/types"
"rpc_api_demo/rpc/types/demo"
"rpc_api_demo/rpc/user/userclient" // 假设RPC服务客户端代码已生成在此包中
)
type CreateUserLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewCreateUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateUserLogic {
return &CreateUserLogic{
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *CreateUserLogic) CreateUser(req *types.CreateUserRequest) (resp *types.CreateUserResponse, err error) {
// 调用RPC服务的CreateUser方法
userRpc := userclient.NewUserRpcClient(l.svcCtx.RpcClient) // 假设RpcClient已在svcCtx中注入
createUserResp, err := userRpc.CreateUser(context.Background(), &demo.CreateUserRequest{
Name: req.Name,
Email: req.Email,
})
if err!= nil {
return nil, err
}
return &types.CreateUserResponse{
Code: createUserResp.Code,
Message: createUserResp.Message,
}, nil
}
- 获取用户信息逻辑(userinfologic.go)
- 在
api/user/logic/userinfologic.go文件中编写获取用户信息的逻辑。同样先获取 RPC 服务客户端连接,然后调用 RPC 服务的GetUser方法,代码示例如下:
- 在
package logic
import (
"context"
"rpc_api_demo/api/internal/svc"
"rpc_api_demo/api/internal/types"
"rpc_api_demo/rpc/types/demo"
"rpc_api_demo/rpc/user/userclient"
)
type UserInfoLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewUserInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserInfoLogic {
return &UserInfoLogic{
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *UserInfoLogic) UserInfo(req *types.UserInfoReq) (resp *types.UserInfoResp, err error) {
userRpc := userclient.NewUserRpcClient(l.svcCtx.RpcClient)
userResp, err := userRpc.GetUser(context.Background(), &demo.GetUserRequest{Id: req.Id})
if err!= nil {
return nil, err
}
return &types.UserInfoResp{Id: userResp.Id, Name: userResp.Name, Email: userResp.Email}, nil
}
二、总结与展望
通过以上步骤,我们实现了 API 与 RPC 服务的结合,形成了一个完整的服务调用链路。然而,我们也要认识到目前所涉及的内容还只是 GO-ZERO 的基础部分。在实际项目中,还有许多进阶的功能需要考虑,如异常捕获、监控报警、加解密、日志记录和并发控制等。虽然本次课程未深入讲解这些内容,但希望大家在掌握基础之后,能够通过官方文档进一步学习和探索,不断提升自己在 GO-ZERO 微服务开发方面的能力。
同时,讲师也在思考如何开展一个更实用、更能体现微服务优势且新颖的项目,大家可以持续关注相关动态。本次 GO-ZERO 基础部分教程至此结束,所有相关文档可在博客或官方文档中获取(虽然官方文档更新可能较慢)。感谢大家的学习与支持!
439

被折叠的 条评论
为什么被折叠?



