目录
1、OpenAPI Generator简介
1.1 OpenAPI Generator是什么?
OpenAPI Generator 是一个完全免费开源 (Apache 许可 v2) 的项目,用来生成 REST1 API 客
户端、服务器存根和基于 OpenAPI (以前称为 Swagger ) 规范的文档。如果您不熟悉
OpenAPI 规范,那么它就是描述 RESTful API 方面最流行的标准,并得到 Adobe,Atlassian
,CA Technologies,eBay,IBM,Google,Microsoft,PayPal、Salesforce,SAP,
SmartBear 等众多知名公司的支持2。有关 OpenAPI 2.0 的完整规范,请参阅 Github 中的项目页面: https://github.com/OpenAPITools/openapi-generator
1.2 为什么选择OpenAPI Generator?
OpenAPI Generator 旨在让 IT 专业人员在时间和人力方面获得巨大的节省。传统的方法是手动编写和维护 API 客户端和文档,如果 API 仅有几个端点,并且要求仅以一种或两种编程语 言提供软件开发工具包 (SDK),那么手工方法还不算是一种糟糕的方法。但是随着 API 的增长越来越大,手动方法将无法扩展以满足不断变化的需求,这正是 OpenAPI Generator 所发挥的作用。OpenAPI Generator 使用的是契约优先的方法,API 所有者只需要用新的或修改过的端点来更新规范,然后在几分钟内以各种编程语言生成 SDK 和 对应的API 文档。
OpenAPI Generator 并不是目前市场上唯一一个可用的代码生成工具,所以为什么要选择 OpenAPI Generator 呢?这里有几点能够说服你 OpenAPI Generator 是开发者的不二选择:
-
OpenAPI Generator 是完全免费的,并且使用 Apache 许可证版本2.0开放源代码。自动生成的文件没有任何许可约束,所以您可以将任意认为适当的软件许可证应用于自动生成的代码。
-
OpenAPI Generator 已经被使用在来自 GoDaddy, Telstra, Zalando, Yelp 等许多上市 公司以及很多已经获得多轮风险投资的创业公司包括 Boxever 和 Xero 的实际产品中 ,这意味着项目本身已经成熟并且为产品准备就绪。
-
OpenAPI Generator 的 Github 项目页面上有超过2000颗加星和12000多个提交,说明 该项目有一个充满活力和不断增长的社区。来自世界各地的1100多名软件开发人员已 经提交了至少一个 Pull Request (Git中提出代码更改的标准方法)使 OpenAPI Generator 变得更好。您将在 StackOverflow,Twitter,Github 和其他社交网络上发现 许多与 OpenAPI Generator 相关的活动。有关 OpenAPI Generator 的演示文稿,视频,教程和电子书列表,请参阅 Github 代码库中的自述文件(README)。
-
OpenAPI Generator 支持30多个 API 客户端,25个服务器存根和 API 文档。最近,我们刚刚添加了对 TypeScript (RxJS) 客户端生成器的支持和更多生成器,例Julia 和 Crystal,这些都正在由令人敬畏的社区不断维护和更新。
1.3 谁需要 OpenAPI Generator?
OpenAPI Generator 是一个能够节省大量时间的工具,许多 IT 专业人员都可以从中受益。我们将通过几个例子来展示 OpenAPI Generator 如何改变开发者的工作方式。
-
后端开发人员 - OpenAPI Generator 配备了25多个服务器存根生成器,用于不同的服务器端框架,如 PHP Symfony,C#Nancy,Java Spring,Python Flask 等等。自动生成的服务器端代码允许后端开发人员在给定 OpenAPI/Swagger 2.0 规范文件的情况 下轻松实现 RESTful 后端。
-
前端开发人员 - OpenAPI Generator 对于需要访问 RESTful 后端的前端开发人员来说是一个能够节省大量时间的工具。前端开发人员可以在一分钟之内轻松地使用他们喜欢的语言(如 TypeScript 和 JavaScript)来生成功能齐全的SDK,而无需为 RESTful 后端手动编写精简的包装器或 SDK。目前,TypeScript 客户端生成器支持 AngularJS ,Angular 2.x 和 4.x,Fetch 等,以满足不同的需求。
-
技术编辑 - 保持 API 文档实时更新可能是一件十分艰巨的任务,但是使用 OpenAPI Generator,可以毫不费力地生成最新的 API 文档和最新的 API 规范。技术文档编写者还可以自定义 API 文档的布局,外观和视感,或者通过自定义文档模板来添加新的 部分。
-
质量保证(QA)工程师 - 自动生成的 API 客户端还附带测试文件,QA 工程师可以简单地在框架中填入具体的测试详情,或者轻松创建新的测试用例来涵盖更多的场景。
-
API 传道者 - API 传道者的成功取决于许多因素,其中之一就是有多少开发者在生产中实际使用 API。想象一下,你的初创公司只是启动一个天气预报 API,而 API 传道者将需要鼓励尽可能多的开发者来使用 API。使用 OpenAPI Generator,可以使用10多种编程语言轻松生成功能齐全的 SDK,从而降低了新的开发人员使用 API 的门槛。
2、OpenAPI 2.0规范
在不了解规范的情况下很 难解释 OpenAPI Generator 的输出,市场上有很多工具可以完全支持 OpenAPI 2.0 规范。简 单举几个例子:ReadyAPI,Postman,Runscope。随着该规范逐渐成为这些 API 工具的通 用语言,理解它将帮助您轻松纵览 API 生态系统。
学习 OpenAPI 2.0 规范的最好方法就是分析实际案例。在本书中,我们将主要使用 Pet Store API 规范 https://raw.githubusercontent.com/openapi-generator-ebook/spec/master/petstore.json,该 规范描述了一个带有若干操作和模型的在线宠物商店的 RESTful API。JSON 和 YAML 都可以用来表示规范。请注意,所有字段名称都区分大小写。
2.1 基础
先看看REST API的基本信息:
swagger: '2.0'
info:
description: 'This is a sample server Petstore server ...'
version: 1.0.0
title: Swagger Petstore
termsOfService: 'http://swagger.io/terms/'
contact:
email: apiteam@swagger.io
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
host: petstore.swagger.io
basePath: /v2
schemes:
- http
“swagger” 声明了规范的版本,我们的例子中该版本为 2.0。OpenAPI 规范 3.0 是 OpenAPI/Swagger 规范 2.0 的继承者。
“info” 提供了有关 API 的各种信息,如版本,联系人,许可证等。这里只有 “title” 和 “version” 是必填字段,您可以通过以下链接了解更多信息:https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#info-object
“host” 是 API 的主机名。也可以使用 IP 地址,例如 192.168.7.5:8080。 “basePath” 是 API 的服务的根路径。这是所有端点共享的公共 URL,如果端点不共享公共 URL,则可以省略。考虑以下端点 URL:
例如:https://api.codegen.org:8080/v3/api/generator
这个 “host” 是 api.codegen.org:8080 和 “basePath” 是/ V3/API,这里所有的端点的路径中
都会包含 /V3/API。
“schemes” 是 API 的传输协议,必须是以下值之一:http,https,ws,wss
有关这些顶级字段的更多信息,请参阅官方 OpenAPI 规范 2.0 中的 “模式” 部分: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#schema
2.2 标签
规范的下一部分是 “tags”,可以用来对端点进行分类。这里举一个例子:
tags:
- name: pet
description: Everything about your Pets
externalDocs:
description: Find out more
url: 'http://swagger.io'
然后,我们可以用 “pet”(区分大小写)标签标记所有与宠物有关的操作。
2.3 安全性定义
“securityDefinitions” 描述了端点所需要的认证机制。目前,支持三种机制:放置于头部或查 询参数中的 API 密钥,HTTP 基本认证和 OAuth2 令牌授权。一个端点可以有多种认证机制。 这里举一个例子:
securityDefinitions:
petstore_auth:
type: oauth2
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
flow: implicit
scopes:
'write:pets': modify pets in your account
'read:pets': read your pets
api_key:
type: apiKey
name: api_key
in: header
有关安全性定义的详细信息,请参阅官方 OpenAPI 2.0 规范中的 “Security Schema Object” 部分:https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#securityScheme Object
3、OpenAPI Generator实践
3.1 问题背景
- 背景:假设现在我们已经有一个历史服务在运行了,对应的代码为:open_ability_server.py
- 需求:想给这个代码生成各种语言对应的SDK
- 问题:第一次实现SDK可能觉得还好,但是随着服务的升级,我们需要很大的成本来维护不同的SDK,这样效率非常低,而且容易出错
open_ability_server.py
安装依赖后直接启动即可,默认使用的8080端口启动服务,有2个接口:/health、/open_ability。
# -*- coding: UTF-8 -*-
"""
# rs勿忘初心
"""
from flask import Flask
from flask_restful import Api
from flask import jsonify, request
from flask import make_response
app = Flask(__name__)
app.config["DEBUG"] = True
api = Api(app)
@app.route('/health', methods=["GET", "POST"])
def health():
"""
# 健康检查接口
:return:
"""
result = {
"code": "200",
"message": "success",
"data": "green"
}
return make_response(jsonify(result))
@app.route('/open_ability', methods=["POST"])
def open_ability():
"""
# 开放能力接口
:return:
"""
request_data = request.json
# 默认值
env_name = "sandbox"
if "param_dict" in request_data and "env_name" in request_data["param_dict"]:
env_name = request_data["param_dict"]["env_name"]
result = {
"code": 0,
"msg": "{} 环境检查符合预期, 可以正常使用".format(env_name),
"need_push": 1,
"status": "success"
}
return make_response(jsonify(result))
if __name__ == "__main__":
# 启动服务
app.run(host="0.0.0.0", port=8080, debug=False)
3.2 编写服务对应的规范文件
首先我们需要编写服务对应的yaml规范文件,其实就是要符合openapi的要求。
可以在各IDE中安装对应的插件来编写yaml文件,比如PyCharm中的"OpenAPI(Swagger)"插件,也可以在线编写:Swagger Editor
opentesting.yaml
openapi: "3.0.2"
info:
title: API Title
version: "1.0"
servers:
- url: http://127.0.0.1:8080/
paths:
/health:
get:
responses:
"200":
content:
application/json:
schema:
additionalProperties:
format: string
type: string
type: object
description: successful operation
/open_ability:
post:
summary: Add a new pet to the store
description: ''
operationId: open_ability
responses:
"200":
content:
application/json:
schema:
type: object
description: successful operation
'405':
description: Invalid input
requestBody:
$ref: '#/components/requestBodies/Command'
components:
requestBodies:
Command:
content:
application/json:
schema:
$ref: '#/components/schemas/Command'
description: Pet object that needs to be added to the store
required: true
schemas:
Command:
title: a Command
description: A pet for sale in the pet store
type: object
required:
- task_id
- message_from
- command_name
- content
- param_dict
properties:
task_id:
type: string
example: 123
message_from:
type: string
example: rongsong
command_name:
type: string
example: env_check
content:
type: string
example: !help
param_dict:
type: object
status:
type: string
description: pet status in the store
deprecated: true
enum:
- available
- pending
- sold
xml:
name: Pet
Category:
title: Pet category
description: A category for a pet
type: object
properties:
env_name:
type: string
example: dev
ApiResponse:
title: An uploaded response
description: Describes the result of uploading an image resource
type: object
properties:
code:
type: integer
format: int32
type:
type: string
message:
type: string
3.3 生成python语言版本对应的SDK
使用homebrew安装工具openapi-generator:
brew install openapi-generator
新建一个文件夹,假设名字为opentesting,然后将刚才的opentesting.yaml文件放置其中,然后执行如下命令:
openapi-generator generate -i opentesting.yaml -g python -o .
若没有报错的话,预期自动生成的代码文件结构如下所示:
.
├── README.md
├── docs
│ ├── ApiResponse.md
│ ├── Category.md
│ ├── Command.md
│ └── DefaultApi.md
├── git_push.sh
├── openapi_client
│ ├── __init__.py
│ ├── api
│ │ ├── __init__.py
│ │ └── default_api.py
│ ├── api_client.py
│ ├── apis
│ │ └── __init__.py
│ ├── configuration.py
│ ├── exceptions.py
│ ├── model
│ │ ├── __init__.py
│ │ ├── api_response.py
│ │ ├── category.py
│ │ └── command.py
│ ├── model_utils.py
│ ├── models
│ │ └── __init__.py
│ └── rest.py
├── opentesting.yaml
├── requirements.txt
├── setup.cfg
├── setup.py
├── test
│ ├── __init__.py
│ ├── test_api_response.py
│ ├── test_category.py
│ ├── test_command.py
│ └── test_default_api.py
├── test-requirements.txt
└── tox.ini
从自动生成的README.md文档可以看出,整个结构比较清晰的,包括一些接口文档其实都已经帮我们自动做好了,我们基于【Getting Started】部分给出了一个简单的demo示例,测试以sdk的方式访问我们的服务(opentesting的2个接口:/health、/open_ability),如下:
demo.py
# -*- coding: UTF-8 -*-
"""
@Time : 2022/6/30 20:01
@Auth : rs
"""
import time
import openapi_client
from pprint import pprint
from openapi_client.api import default_api
from openapi_client.model.command import Command
from openapi_client.model.category import Category
# Defining the host is optional and defaults to https://127.0.0.0:8080
# See configuration.py for a list of all supported configuration parameters.
configuration = openapi_client.Configuration(
host="http://127.0.0.1:8080"
)
# Enter a context with an instance of the API client
with openapi_client.ApiClient(configuration) as api_client:
# Create an instance of the API class
api_instance = default_api.DefaultApi(api_client)
try:
api_response = api_instance.health_get()
pprint(api_response)
request_data = Command(
task_id="xxxxxxxxx",
message_from="rongsong",
command_name="env_check",
content="",
param_dict={
"env_name": "dev"
}
)
api_response = api_instance.open_ability(request_data)
pprint(api_response)
except openapi_client.ApiException as e:
print("Exception when calling DefaultApi->health_get: %s\n" % e)
预期运行结果如下:
{'code': '200', 'data': 'green', 'message': 'success'}
{'code': 0.0,
'msg': 'dev 环境检查符合预期, 可以正常使用',
'need_push': 1.0,
'status': 'success'}
4、常见问题
4.1 修改了yaml定义文件后怎么办?
答:确认无误后,直接重新生成sdk即可。
openapi-generator generate -i opentesting.yaml -g python -o .
4.2 可以生成flask框架的server代码吗?
答:可以的,但是有些冗余(可能是我看不要懂),这个只是给出了一个架子,具体的接口函数也需要你自己实现。执行命令类似如下:(注意新建一个文件夹操作)
openapi-generator generate -i opentesting.yaml -g python-flask -o .