add goa description

Update README.md

add placeholders

add pl

fix typo && add some useful external docs

fix typo && add some useful external docs
This commit is contained in:
CaptainNEO 2022-03-07 21:23:06 +08:00
parent e2fd9f666e
commit 2c8ba685a3

239
README.md
View File

@ -1,58 +1,223 @@
[[_TOC_]]
# OpenAPI3 Framworks Compare
本文会横向对比几种支持OpenAPI文档生成的工具/框架。
OpenAPI 规范(OAS定义了一个标准的、语言无关的 RESTful API 接口规范,它可以同时允许开发人员和操作系统查看并理解某个服务的功能,而无需访问源代码,文档或网络流量检查(既方便人类学习和阅读,也方便机器阅读)。正确定义 OAS 后,开发者可以使用最少的实现逻辑来理解远程服务并与之交互。
OpenAPI Specification下文简称OAS定义了一个标准的、语言无关的 RESTful API 接口规范,它可以同时允许开发人员和操作系统查看并理解某个服务的功能,而无需访问源代码,文档或网络流量检查(既方便人类学习和阅读,也方便机器阅读)。正确定义 OAS 后,开发者可以使用最少的实现逻辑来理解远程服务并与之交互。
此外,文档生成工具可以使用 OpenAPI 规范来生成 API 文档代码生成工具可以生成各种编程语言下的服务端和客户端代码测试代码和其他用例。OpenAPI官方提供了各种语言的服务端和客户端的代码生成工具比较著名的如[OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator),当然也有很多优秀的第三方开发者开发的工具。
> 相关参考
> 参考阅读
>
> - [OpenAPI3 Specification官方文档(v3.0.3)](https://spec.openapis.org/oas/v3.0.3) Published 20 February 2020
> - [OpenAPI3 Specification官方文档(v3.1.0)](https://spec.openapis.org/oas/v3.1.0) Published 15 February 2021
> - [Awesome OpenAPI3](https://apis.guru/awesome-openapi3)
## 1. 背景描述
## 1. 项目背景
使用如上几种框架分别实现Swagger官方用例[petstore](https://petstore.swagger.io)中的一部分然后分析这些框架的实现方式和背后生成OpenAPI的逻辑
目前公司内部开发中的项目存在很多接口文档规范不统一、实现不一致的问题。据笔者的了解,起码目前存在以下的几种维护方式。
1. 使用[swag](https://github.com/swaggo/swag)工具在代码中加入注解,然后通过代码生成对应项目的文档
2. 一些使用grpc-gateway的grpc项目会使用其附带的[protoc-gen-openapiv2](https://github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2)工具对protobuf文件进行分析生成对应的文档
3. 在yapi中手撸接口文档
4. 纯手动自己维护一个自定义格式的HTML文档
其中前两种方式使用工具生成,后两种完全靠双手自行维护。除第二种方式外,其他三种方式都多少依赖维护者的自觉性,维护得好皆大欢喜,维护得不好就会引发一系列的连锁反应。
- 新人接手项目。目前维护的这个服务提供了哪些能力?接手新需求的时候我是要新增一个接口还是已经存在类似的接口,只需要扩展一下?如果没有完整的接口文档,只能硬啃现有代码。如果代码量比较巨大的话会非常痛苦,或者疑惑我应该信代码还是信文档?会不会是代码实现有失误的地方?总之满头问号
- 前后端对接、服务间对接。参数描述基本靠飞书返回描述基本靠Chrome开发者工具。一个维护得足够久的接口没有人能够描述出来到底返回什么样的结构需要传递哪些参数怎么传哪些必传这些参数有哪些约束条件或者一些已经废弃的参数可能早就无人使用但是没人敢删除。到达某种状态后只能是懒得细扣代码继续往上加。 总结:口头对接一时爽,事后复盘火葬场。
- 重构。项目到达一定的复杂程度、或者随着产品的不断迭代,接口可能会面临着重构。如果没有足够的测试代码且对接口行为没有完全十足的把握的话,重构无疑会存在着巨大的风险,一不小心在某个获取参数的地方导致行为不一致、或者返回的结构有差别的话就会导致整个下游服务的行为异常。
这也是OAS存在的理由如果所有的服务都使用了某种方式能从代码中生产出对应可信赖的、接口描述与代码行为严格同步的OAS文档上述的所有问题都会迎刃而解而且可以利用上社区内已经非常丰富的OAS生态相关工具包括sdk生成、文档渲染工具等等。因为所有的文档都是标准的规范甚至可以团队自己开发自己需要的工具提升开发效率。一旦完善趋于完善还可以做一些更有趣的事情比如:
1. 公司内所有服务可版本溯源的HTTP API接口文档查询工具。
2. 接通内管平台,对所有服务的接口管理。设定接口权限?联动网关层(如Istio)实现一个可视化的流量看板?
既然如上列举的各种优势现在摆在眼前的问题只有一个那就是实现代码和OAS文档同步带来的额外工作量和难度如果开发流程对开发者过于繁琐且耗时那么必定在推广的时候困难重重。所以现在的情况就是寻找一个可以快速、简便地维护OAS文档的方法
1. 找现成的开源方案
2. 自己造轮子
知己知彼,才能百战不殆。所以本项目的目的就是借鉴前人的设计和想法,总结好的设计方法,摒弃不好的设计方法。尽可能多的去了解别人是怎么做这件事情的,才能更好地去完成自己的。
以下内容会分别使用几种包含`从代码中同步文档`feature的框架(欢迎补充)用其实现一些简单的用例然后分析这些框架的实现方式和背后生成OAS的逻辑。随后会加上一些笔者的主观评价。
## 2. 参赛选手介绍
| 语言 | 框架 | Web功能完备 | OpenAPI版本 | Github Stars | 当前版本 | first release datae |
|--------|--------------------------------------------------------------------------|-------------|-------------|--------------------------------------------------------------------------------|------------------------------------------------------------------------------------|---------------------|
| Go | [goa](https://github.com/goadesign/goa) | 是 | 3 | ![stars](https://img.shields.io/github/stars/goadesign/goa.svg) | ![Release](https://img.shields.io/github/tag/goadesign/goa.svg) | 2016-08-03 |
| Go | [swag](https://github.com/swaggo/swag) | 否 | 2 | ![stars](https://img.shields.io/github/stars/swaggo/swag.svg) | ![Release](https://img.shields.io/github/release/swaggo/swag.svg) | 2017-11-30 |
| Go | [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) | 是 | 2 | ![stars](https://img.shields.io/github/stars/grpc-ecosystem/grpc-gateway.svg) | ![Release](https://img.shields.io/github/release/grpc-ecosystem/grpc-gateway.svg) | 2016-07-11 |
| Go | [fizz](https://github.com/wI2L/fizz) | 是 | 3 | ![stars](https://img.shields.io/github/stars/wI2L/fizz.svg) | ![Release](https://img.shields.io/github/release/wI2L/fizz.svg) | 2019-11-06 |
| Python | [Django REST framework](https://github.com/encode/django-rest-framework) | 是 | 3 | ![stars](https://img.shields.io/github/stars/encode/django-rest-framework.svg) | ![Release](https://img.shields.io/github/release/encode/django-rest-framework.svg) | 2011-02-22 |
| Python | [FastAPI](https://github.com/tiangolo/fastapi) | 是 | 3 | ![stars](https://img.shields.io/github/stars/tiangolo/fastapi.svg) | ![Release](https://img.shields.io/github/release/tiangolo/fastapi.svg) | 2018-12-16 |
| Rust | [Poem](https://github.com/poem-web/poem) | 是 | 3 | ![stars](https://img.shields.io/github/stars/poem-web/poem.svg) | ![Release](https://img.shields.io/github/tag/poem-web/poem.svg) | 2021-10-14 |
| 语言 | 框架 | Web功能完备 | OpenAPI版本 | Github Stars | 当前版本 | first release date |
|--------|--------------------------------------------------------------------------|-------------|-------------|--------------------------------------------------------------------------------|------------------------------------------------------------------------------------|--------------------|
| Go | [goa](https://github.com/goadesign/goa) | 是 | 3 | ![stars](https://img.shields.io/github/stars/goadesign/goa.svg) | ![Release](https://img.shields.io/github/tag/goadesign/goa.svg) | 2016-08-03 |
| Go | [swag](https://github.com/swaggo/swag) | 否 | 2 | ![stars](https://img.shields.io/github/stars/swaggo/swag.svg) | ![Release](https://img.shields.io/github/release/swaggo/swag.svg) | 2017-11-30 |
| Go | [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) | 是 | 2 | ![stars](https://img.shields.io/github/stars/grpc-ecosystem/grpc-gateway.svg) | ![Release](https://img.shields.io/github/release/grpc-ecosystem/grpc-gateway.svg) | 2016-07-11 |
| Go | [fizz](https://github.com/wI2L/fizz) | 是 | 3 | ![stars](https://img.shields.io/github/stars/wI2L/fizz.svg) | ![Release](https://img.shields.io/github/release/wI2L/fizz.svg) | 2019-11-06 |
| Python | [Django REST framework](https://github.com/encode/django-rest-framework) | 是 | 3 | ![stars](https://img.shields.io/github/stars/encode/django-rest-framework.svg) | ![Release](https://img.shields.io/github/release/encode/django-rest-framework.svg) | 2011-02-22 |
| Python | [FastAPI](https://github.com/tiangolo/fastapi) | 是 | 3 | ![stars](https://img.shields.io/github/stars/tiangolo/fastapi.svg) | ![Release](https://img.shields.io/github/release/tiangolo/fastapi.svg) | 2018-12-16 |
| Rust | [Poem](https://github.com/poem-web/poem) | 是 | 3 | ![stars](https://img.shields.io/github/stars/poem-web/poem.svg) | ![Release](https://img.shields.io/github/tag/poem-web/poem.svg) | 2021-10-14 |
## 3. 实现过程介绍
## 3. 详细对比
所有框架均会从以下几个方面进行讨论
1. 开发过程
2. OAS的实现方式: 如何从代码生成对应的sepc文件
3. 优点:该框架的一些特色或者相比其他框架有优势的地方
4. 缺点:该框架的一些劣势,或者不使用的理由
> 以下所有评价均为个人意见,欢迎不同意见
### 1. Goa
```bash
## 1. 安装goa提供的代码生成工具
go install goa.design/goa/v3/cmd/goa@v3
#### 1. 开发过程
## 2. 创建一个design文件夹用于描述API
mkdir -p goa_example/design
1. 安装goa提供的代码生成工具
## 3. 使用goa提供的dsl描述API
```bash
go install goa.design/goa/v3/cmd/goa@v3
```
## 4. 生成代码模板
goa gen goa_example/design
# 该步骤会生成gen文件夹中的所有文件包括design文件中定义的所有接口信息、Model描述、验证方式、Protobuf描述(如果有)等所有相关信息的Go描述
2. 创建一个design文件夹用于描述API
## 5. (optional) 生成实现的一个example
goa example goa_example/design
# 该步骤会生成cmd文件夹包括http server和 grpc server的启动
# 和项目根目录/{service_name}.go的文件其中包含了各方法的默认实现(fmt.Println())
# 接下来只需要修改各方法中的具体实现为真实业务逻辑即可
```
```bash
mkdir -p goa_example/design
```
1. 优点
3. 使用goa提供的dsl描述API
[desigin.go](go/goa_example/design/design.go)
4. 生成代码模板
```bash
goa gen goa_example/design
```
该步骤会生成gen文件夹中的所有文件包括design文件中定义的所有接口信息、Model描述、验证方式、Protobuf描述(如果有)等所有相关信息的Go描述
5. (optional) 生成实现的一个example
```bash
goa example goa_example/design
```
该步骤会生成cmd文件夹包括http server和 grpc server的启动代码
和项目根目录/{service_name}.go的文件其中包含了各方法的默认实现(fmt.Println())
6. 完成代码实现
接下来只需要修改各方法中的具体实现为真实业务逻辑即可[service1.go](go/goa_example/service1.go)
#### 2. OAS的实现方式
OAS中的所有对象均使用框架自定的DSL实现定义design.go文件的同时gen程序可以获得一个API的所有描述信息。
然后根据这些描述信息代码生成所需要的各种类型和interface、包括OAS描述文件让用户尽可能的少写重复代码只去完成关键逻辑。
#### 3. 优点
1. 可同时生成HTTP和Grpc两种服务对应的实现比较完整基本可以描述所有类型的API
2. 生成的代码质量比较高提供的代码抽象比较好。基本上只需要完成业务逻辑的实现就可以。其中甚至包含了分别使用http和grpc请求远端的命令行请求工具
#### 4. 缺点
1. 提供的DSL学习曲线很高其基于查询调用栈的API设计使得所有的函数均为灵活的不定长interface{}传参,除非熟练工,否则因为没有任何代码提示导致使用体验非常差。
2. Model的描述方式虽然定制能力比较高但是定义过程相当繁琐不够直观。
3. 使用时需要对OAS有足够的了解否则不能很好地去合理设计API。
4. 社区内相对比较小众。(6年积累了star 4.5k)
5. 因为定制程度非常高可能导致一些特殊情况需要自定义http行为不容易实现。
### 2. swag
#### 1. 开发过程
#### 2. OAS的实现方式
TODO
#### 3. 优点
TODO
#### 4. 缺点
TODO
### 3. grpc-gateway
#### 1. 开发过程
#### 2. OAS的实现方式
TODO
#### 3. 优点
TODO
#### 4. 缺点
TODO
### 4. Fizz
#### 1. 开发过程
#### 2. OAS的实现方式
TODO
#### 3. 优点
TODO
#### 4. 缺点
TODO
### 5. Django REST Framework
#### 1. 开发过程
#### 2. OAS的实现方式
TODO
#### 3. 优点
TODO
#### 4. 缺点
TODO
### 6. FastAPI
#### 1. 开发过程
#### 2. OAS的实现方式
TODO
#### 3. 优点
TODO
#### 4. 缺点
TODO
### 7. Poem
#### 1. 开发过程
#### 2. OAS的实现方式
TODO
#### 3. 优点
TODO
#### 4. 缺点
TODO
## 4. FAQ
@ -70,12 +235,14 @@ Swagger最初是在2010年设计RESTful API的简单开源规范。还开发了
此后Swagger已成为最受欢迎的工具套件可在整个 API 生命周期中充分利用 OAS 的强大功能。
SmartBear Software 支持的 Swagger 工具是最流行的实现 OpenAPI 规范的工具之一,并将继续保持 Swagger 名称Swagger Editor、Swagger UI、SwaggerHub 等)
> 参考阅读 <https://nordicapis.com/whats-the-difference-between-swagger-and-openapi/>
### 2. JSON Schema?
JSON Schema 是一种定义JSON格式的规范相关生态已经比较完备各种语言的校验工具基本都有实现
例如vscode中配置文件的代码补全和校验就是基于json schema完成的
例如vscode中配置文件的代码补全和校验就是基于json schema完成的
JSON Schema 是一种定义JSON格式的规范相关生态已经比较完备各种语言的校验工具基本都有实现
OpenAPI中对Json对象的描述就是使用Json schema来描述的
目前为止已经发布了多个版本的草案,其中
OAS3.0.3 采用的是Draft 00
OAS3.1.0 采用的是Draft 2020-12
OpenAPI中对Json对象的描述就是使用Json schema来描述的
目前为止已经发布了多个版本的草案,其中
OAS3.0.3 采用的是Draft 00
OAS3.1.0 采用的是Draft 2020-12