RPC 服务结合 API:构建完整的分布式应用架构

目录

 RPC 服务结合 API:构建完整的分布式应用架构

一、项目结构规划

二、编写 RPC 服务的 proto 文件

三、生成 RPC 服务代码

四、编写 RPC 服务逻辑

五、配置 RPC 服务

六、编写 API 的相关文件

七、生成 API 代码

八、编写 API 逻辑实现服务调用

九、配置 API 服务

十、启动服务


在现代分布式应用开发中,将 RPC 服务与 API 相结合是一种常见且有效的架构模式。RPC 服务专注于内部业务逻辑的实现和高效的服务间通信,而 API 则提供对外的接口,方便与前端或其他外部系统进行交互。本文将详细介绍如何实现 RPC 服务与 API 的结合,包括创建项目结构、编写 proto 文件、生成代码、配置服务、编写 API 逻辑以及实现服务调用等步骤,并附上相应的代码示例。

一、项目结构规划

  1. 创建项目目录
    • 新建一个项目目录,例如rpc_api_demo
    • 在项目目录下创建rpcapi目录,分别用于存放 RPC 相关文件和 API 相关文件。
  2. RPC 服务目录结构
    • rpc目录下创建user目录(以用户服务为例),用于存放用户相关的 RPC 服务文件。
    • user目录下创建etcinternalmodel目录(model目录用于存放与数据库交互相关的模型代码,若不涉及数据库操作可暂不创建)。etc目录存放服务配置文件,internal目录存放服务内部逻辑代码。
  3. API 目录结构
    • api目录下创建user目录,用于存放用户相关的 API 文件。
    • user目录下创建etcinternallogic目录。etc目录存放 API 配置文件,internal目录存放 API 相关的结构体和接口定义,logic目录存放 API 的具体逻辑实现。

二、编写 RPC 服务的 proto 文件

  1. 创建 user.proto 文件(rpc/user)
    • rpc/user目录下创建user.proto文件。
    • 定义服务接口,例如创建一个名为UserRpc的服务,包含GetUser方法用于根据用户 ID 获取用户信息,CreateUser方法用于创建新用户等。
    • 示例代码如下:
syntax = "proto3";

service UserRpc {
    rpc GetUser (GetUserRequest) returns (GetUserResponse);
    rpc CreateUser (CreateUserRequest) returns (CreateUserResponse);
}

message GetUserRequest {
    int32 id = 1;
}

message GetUserResponse {
    int32 id = 1;
    string name = 2;
    string email = 3;
}

message CreateUserRequest {
    string name = 1;
    string email = 2;
}

message CreateUserResponse {
    int32 code = 1;
    string message = 2;
}

三、生成 RPC 服务代码

  1. 执行生成命令
    • 在终端中,进入rpc目录(确保已安装goctl工具)。
    • 执行以下命令将user.proto文件转换为对应的 GO 代码:
goctl proto -I. --go_out=. --go-grpc_out=. user.proto

  • 此命令会在rpc目录下生成一系列文件,包括user.pb.gouser_grpc.pb.go等,这些文件包含了 RPC 服务的客户端和服务端的基本代码结构,以及与 proto 文件中定义的消息和服务对应的 Go 结构体和接口。

四、编写 RPC 服务逻辑

  1. 在 internal 目录下编写逻辑代码(rpc/user/internal/logic)
    • GetUser方法为例,在rpc/user/internal/logic/userrpcgetuserlogic.go文件中实现其逻辑。假设这里涉及数据库查询操作(若不涉及则可根据实际业务逻辑编写),首先需要配置数据库连接(参考之前关于 RPC 服务使用 GORM 的部分)。
    • 示例代码如下(假设已经配置好数据库连接并创建了User模型结构体和操作方法):

package logic

import (
    "context"

    "rpc_api_demo/rpc/internal/svc"
    "rpc_api_demo/rpc/types/demo"
    "rpc_api_demo/rpc/user/model"
)

type UserRpcGetUserLogic struct {
    ctx    context.Context
    svcCtx *svc.ServiceContext
}

func NewUserRpcGetUserLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserRpcGetUserLogic {
    return &UserRpcGetUserLogic{
        ctx:    ctx,
        svcCtx: svcCtx,
    }
}

func (l *UserRpcGetUserLogic) GetUser(in *demo.GetUserRequest) (*demo.GetUserResponse, error) {
    // 获取数据库连接
    db := l.svcCtx.DB
    // 创建User模型实例
    userModel := model.User{DB: db}
    // 调用模型方法查询用户信息
    user, err := userModel.FindUserByID(db, in.Id)
    if err!= nil {
        return nil, err
    }
    return &demo.GetUserResponse{Id: user.ID, Name: user.Name, Email: user.Email}, nil
}

  • 同样,在rpc/user/internal/logic/userrpccreateuserlogic.go文件中实现CreateUser方法的逻辑,例如将新用户信息插入数据库并返回相应结果。

五、配置 RPC 服务

  1. 在 etc 目录下创建配置文件(rpc/user/etc/user.yaml)
    • rpc/user/etc目录下创建user.yaml文件。
    • 配置服务的相关信息,如服务名称、监听地址和端口等,若涉及数据库操作还需配置数据库连接信息。
    • 示例配置如下(假设使用 MySQL 数据库):

Name: userrpc
Host: 0.0.0.0
Port: 8080
Mysql:
  DataSource: root:root@tcp(127.0.0.1:3306)/your_database?charset=utf8mb4&parseTime=True&loc=Local

  • your_database替换为实际的数据库名,根据实际情况修改用户名、密码和端口号等。

六、编写 API 的相关文件

  1. 编写 user.api 文件(api/user)
    • api/user目录下创建user.api文件。
    • 定义 API 接口,例如创建获取用户信息的接口和创建用户的接口,与 RPC 服务中的方法相对应。
    • 示例代码如下:

// 获取用户信息接口
// @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 代码

  1. 执行生成命令
    • 在终端中,进入api目录。
    • 执行以下命令将user.api文件转换为对应的 GO 代码:

goctl api go -api user.api -dir.

  • 此命令会在api目录下生成一系列文件,包括handlerlogic等相关文件,构建了 API 的基本框架。

八、编写 API 逻辑实现服务调用

  1. 在 logic 目录下编写逻辑代码(api/user/logic)
    • 以获取用户信息接口为例,在api/user/logic/userinfologic.go文件中实现其逻辑。
    • 首先需要创建 RPC 服务客户端连接,然后调用 RPC 服务的GetUser方法获取用户信息并返回给 API 调用者。
    • 示例代码如下:

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"
    "github.com/zeromicro/go-zero/zrpc"
)

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) {
    // 创建RPC服务客户端连接
    userRpcConn := zrpc.MustNewClient(zrpc.RpcClientConf{
        Endpoints: []string{"127.0.0.1:8080"},
    })
    userRpc := userclient.NewUserRpcClient(userRpcConn)

    // 调用RPC服务的GetUser方法
    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/user/logic/createuserlogic.go文件中实现,调用 RPC 服务的CreateUser方法并处理响应。

九、配置 API 服务

  1. 在 etc 目录下创建配置文件(api/user/etc/user.yaml)
    • api/user/etc目录下创建user.yaml文件。
    • 配置 API 服务的相关信息,如端口号等。
    • 示例配置如下:

port: 8888

十、启动服务

  1. 启动 RPC 服务
    • 在终端中,进入rpc/user目录。
    • 执行go run main.go(或者go run user.go,根据实际文件名而定)启动 RPC 服务。
  2. 启动 API 服务
    • 进入api/user目录。
    • 执行go run user.go启动 API 服务。

通过以上步骤,我们成功地实现了 RPC 服务与 API 的结合。在实际应用中,这种架构可以充分发挥 RPC 服务和 API 的优势,实现高效的内部业务处理和友好的外部接口提供。同时,可以进一步优化和扩展,如添加服务治理、安全认证、缓存机制等,以构建更加稳定、可靠和高效的分布式应用系统。希望本文能够帮助大家更好地理解和应用 RPC 服务与 API 的结合技术。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值