|
|
|
|
| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 |
|
|
|
|
|
| ----- | ----- | ----- | ----- | ----- | ----- |
|
|
|
|
|
| 006| 北野 | 2022-11-23 | 2022-01-01 | v1.0 | 提议 |
|
|
|
|
|
|
|
|
|
|
### 关于paopao-ce的结构设计
|
|
|
|
|
本文档主要讨论paopao-ce目前的代码结构,简要清晰的描述一个**API请求**从 **接受解析->逻辑处理->结果响应**的大概路径,帮助开发人员快速了解paopao-ce代码基的基本面,更好的融入paopao-ce的开发中做出PR贡献。
|
|
|
|
|
![](.assets/006-01.png)
|
|
|
|
|
|
|
|
|
|
### 两种服务 - RESTful API服务 与 gRPC服务
|
|
|
|
|
paopao-ce提供RESTful API与gRPC两种类型子服务,并且拥有**单实例多服务运行**的机制。RESTful API服务基于[gin](https://github.com/gin-gonic/gin)引擎实现,使用[go-mir](https://github.com/alimy/mir)脚手架辅助工具集实现RESTFul API从接口定义到代码自动生成的便捷开发体验。 gRPC服务使用[buf](https://github.com/bufbuild/buf)自动化辅助工具对gRPC服务从 `*.proto` DSL服务接口定义到接口代码自动生成的全流程管理。
|
|
|
|
|
|
|
|
|
|
### 结构说明
|
|
|
|
|
paopao-ce采用清晰的分层结构设计,主要包括 **接入层、业务逻辑层、数据逻辑层、数据存储**。
|
|
|
|
|
* 接入层
|
|
|
|
|
RESTful API服务的接入层由 [gin](https://github.com/gin-gonic/gin)引擎 与 [go-mir](https://github.com/alimy/mir)生成的 **Binding/Render** 代码共同组成。当一个HTTP Request被http server接受后,通过[gin](https://github.com/gin-gonic/gin)的路由机制,由相应的[go-mir](https://github.com/alimy/mir)生成的`Binding`将请求解析后传入 **业务逻辑层**中相对应的 子服务Servants 完成业务处理后获得结果,[go-mir](https://github.com/alimy/mir)生成的`Render`把结果渲染后生成对应的 HTTP Response发送出去以完成一个HTTP请求。
|
|
|
|
|
gRPC服务的接入层由其对应的gRPC服务器引擎组成,当一个RPC请求过来后,先把请求解码解析后传入 **业务逻辑层**中相对应的 子服务Servers 完成业务处理后获得结果,将处理结果编码后生成对应的 HTTP Response发送出去就完成了一个RPC请求的完整流程。
|
|
|
|
|
* 业务逻辑层
|
|
|
|
|
RESTful API服务的业务逻辑层是由[go-mir](https://github.com/alimy/mir)依据接口定义自动生成的**Servants服务接口**组成,开发人员需要实现这些接口以提供相应的业务逻辑。gRPC也是一样的,业务逻辑需要通过实现gRPC依据proto DSL定义接口自动生成的服务接口来提供相应业务处理服务。
|
|
|
|
|
* 数据逻辑层
|
|
|
|
|
paopao-ce将所有与数据存储相关的服务都统一定义成接口,包括**SQL服务、缓存服务、OBS服务、Search服务** 等,然后根据具体的部署环境选择适配的相应存储服务实现。比如OBS服务,定义了统一的操作对象存储的服务接口,然后提供阿里云、腾讯云、华为云、MinIO、S3、Localoss等的服务适配实现,这样就可以根据不同的部署环境切换使用不同的对象存储服务实现。
|
|
|
|
|
* 数据存储
|
|
|
|
|
数据存储包括 SQL存储(MySQL/PostgreSQL/Sqlite3)、Cache、OBS、Search Engine(Zinc/Meilisearch)等,paopao-ce本身不关心具体的数据存储是如何部署的,一般是通过对应的标准方式连接部署实例以获取相应存储服务。
|
|
|
|
|
|
|
|
|
|
### paopao-ce代码目录的说明
|
|
|
|
|
```sh
|
|
|
|
|
tree -L 2
|
|
|
|
|
.
|
|
|
|
|
|-- auto
|
|
|
|
|
| |-- api
|
|
|
|
|
| `-- rpc
|
|
|
|
|
|-- internal
|
|
|
|
|
| |-- conf
|
|
|
|
|
| |-- core
|
|
|
|
|
| |-- dao
|
|
|
|
|
| |-- ims
|
|
|
|
|
| |-- migration
|
|
|
|
|
| |-- model
|
|
|
|
|
| |-- obs
|
|
|
|
|
| |-- servants
|
|
|
|
|
| `-- service
|
|
|
|
|
|-- main.go
|
|
|
|
|
|-- mirc
|
|
|
|
|
|-- proto
|
|
|
|
|
|-- release
|
|
|
|
|
`-- web
|
|
|
|
|
```
|
|
|
|
|
* 根目录的`mirc`包含RESTful API的[go-mir](https://github.com/alimy/mir)服务接口定义文件, `auto/api`目录包含[go-mir](https://github.com/alimy/mir)自动生成的服务接口代码;
|
|
|
|
|
* 目录`proto`包含gRPC的proto服务接口定义文件,自动生成的服务接口代码包含在`auto/rpc`目录中;
|
|
|
|
|
* 业务逻辑层的代码都包含在`internal/servants`目录,包括RESTful服务以及gRPC服务的业务逻辑处理代码都包含在这个目录中;
|
|
|
|
|
* `internal/core`包含所有数据逻辑层的服务接口定义,相应的数据逻辑层服务接口实现代码都包含在`internal/dao`目录中;
|
|
|
|
|
* 一些大的功能模块统一放置于`internal`目录中,以降低代码目录深度;比如数据库迁移功能模块`migration`的代码包含在`internal/migration`目录、 消息推送功能模块`ims` -> `internal/ims`, 简单本地OBS功能`obs` -> `internal/obs` 等;
|
|
|
|
|
* `internal/service`目录包含paopao-ce所有子服务(`Web`、`Admin`、`Bot`、`SpaceX`、`Mobile` ...)的初始化逻辑代码;
|
|
|
|
|
* `internal/conf`目录包含全局配置相关的逻辑代码;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 疑问
|
|
|
|
|
|
|
|
|
|
1. 为什么要引入[go-mir](https://github.com/alimy/mir)?
|
|
|
|
|
**工欲善其事,必先利其器**。为了RESTFul API的后端开发体验可以媲美gRPC,本人特意打造[go-mir](https://github.com/alimy/mir) v3版本来满足需求。[go-mir](https://github.com/alimy/mir)是一套使用golang自身语言生态实现的RESTFul API从接口定义到代码自动生成的脚手架辅助工具集,便捷的实现快速后端开发体验,颇有 *“程咬金的三板斧,简单抡着就完事”* 的韵味。而从[go-mir](https://github.com/alimy/mir)的官方文档参考也可以看出,其生成的代码也确实就将一个HTTP的请求/响应简单分成 `请求绑定`->`业务逻辑`->`结果渲染`三个步骤去完成,生成的代码结构简单清晰,与gRPC的生成代码有点类似。
|
|
|
|
|
1. 为什么要兼容RESTful服务与gRPC服务?
|
|
|
|
|
RESTful服务与gRPC服务各自有擅长的场景,在合适的场景使用最适合的技术去做相应的适配,这是paopao-ce秉持的代码开发原则之一。
|
|
|
|
|
|
|
|
|
|
### 更新记录
|
|
|
|
|
#### v0.0(2022-11-23) - 北野
|
|
|
|
|
* 初始文档, 先占个位置
|
|
|
|
|
|
|
|
|
|
#### v0.1(2022-12-23) - 北野
|
|
|
|
|
* 添加部分内容
|
|
|
|
|
|
|
|
|
|
#### v1.0(2023-01-01) - 北野
|
|
|
|
|
* 添加部分内容
|