写点什么

聊聊 OpenAPI Specification(OAS)

发布于: 2020 年 12 月 02 日
聊聊OpenAPI Specification(OAS)

估计很多小伙伴对于OpenAPI Specification(OAS)没啥概念,但如果说Swagger,那估计不少就知道了,毕竟现在说要设计或者看API文档,基本都会用到Swagger UI这个工具。其实,Swagger UI要使用到的API规范,就是这OpenAPI Specification,只不过以前叫Swagger Specification,现在已经欢乐马甲,叫OpenAPI Specification。可能不少前端小伙伴对于Swagger的认识,仅限于API文档。当时,你光从这OpenAPI Specification名称上看,就是知道,该规范其实已成为开发者社区里API设计的引领者了。这篇文章带你去探究OAS的前世今生,看看其究竟为啥会火起来,如何使用该规范,以及在应用的时候采的一些坑。

OpenAPI Spec的前世今生

开头已经提到,这OpenAPI Spec其实就是Swagger Spec,而要说Swagger,就不得不提REST APIs了。其实早在2009年的时候,要知道当时基于REST APIs设计架构已经广为流行了,但是还未有针对REST的啥工具,很多时候大家都是各干各的。一位名叫Tony Tam的技术大咖,正苦于此,说凭啥SOAP这种过时设计框架还一大堆工具去支持,而我这每次给客户端搞API文档都是坑。于是说干就干,依照支持SOAP那些工具的特点,按照REST的特色,推出了Swagger的雏形。事实上,Swagger开始推出的口号就是:why WADL(支持SOAP的描述性语言),when you can SWAGR?因此,Swagger一经推出,就是想要在REST API社区掀起大浪。



然而在Swagger推出的早期,也就是在小圈子内搞搞,毕竟这种标准化的东西,没有大厂背书,也就是喊喊口号了。于是Swagger不温不火,社区慢慢流行。直到2015年,Swagger Spec都已经升级到V2版本了,一家叫SmartBear的软件公司收购了这个技术大咖公司,并宣称将在LINUX基金、Googl、IBM

MicroSoft、PayPal等一席大公司的赞助下启动OpenAPI这个组织,并组建专门的技术委员会对其进行管理。后续在不断有大厂和大咖加入下,2017年正式把Swagger Spec改名,推出并定义了OpenAPI Spec。对于OpenAPI Spec的官方定义,由于我没找到任何官方中文,因此,我就放英文原文

The OpenAPI Specification (OAS) defines a standard, language-agnostic interface to HTTP APIs which allows both humans and computers to discover and understand the capabilities of the service without access to source code, documentation, or through network traffic inspection. When properly defined, a consumer can understand and interact with the remote service with a minimal amount of implementation logic.



其实这个定义和早期版本定义还是有点区别的,大家可以对照体会:

The OpenAPI Specification (OAS) defines a standard, programming language-agnostic interface description for REST APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, the OpenAPI Specification removes guesswork in calling a service.



个人感觉目前的定义,应该是妥协了各方的需求,毕竟林子大了,啥鸟都有。即使当前OpenAPI版本,也是无法覆盖所有API设计场景的。但是,早期版本,其实基本上就是基于REST模式或者说Swagger设计理念来的。

OpenAPI Spec的应用场景

OAS的理念就是,只关乎API的设计,与语言无关。在当下设计驱动的理念,其实也是很默契的。毕竟造车都得先有造车的图纸。越是复杂的项目,越是需要对API设计进行规范化。而OAS设计规范和配套相应的工具,在软件开发的各大应用场景中都大放异彩。

APIs设计

OAS的目标就是要用统一的规范,在组织里面使用共同的设计标准和REST接口设计,从而减少设计上的错误,并且还能为API的开发者和使用者,无论是前端工程、后端工程师还是测试工程师,都提供方便使用的接口信息。定义OAS文档的语言,可以选用JSON或者YAML两种语言,但基于可读性,目前社区基本推荐使用YAML语言。目前虽然OAS V3开始流行,但早期的Swagger Spec V2(OAS V2)由于历史包袱原因,大部分工具都是支持两个版本的。通过下面这个图,可以很清楚这两个版本的异同(来源)。



image.png



通过对比,可以发现,OAS V3就是更加开放,就如果其定义一样,更能够适应不同的API设计场景,比如当下比较火热的微服务架构,就是直接定义为hosts,可以对应不同的URLs的服务器。同时,把V2的definitions、parameters等等都直接归为components,这些components为搭建该规范的模块。下面为OAS简单的编写规范,为了更好对比,我在主要参数旁边都加了注释。

openapi: 3.0.1 # OAS的版本, 必须填的参数
info: # OAS的版本,必须填的参数
title: An include file to define sortable attributes
version: 1.0.0 # 元数据版本号,注意和OAS版本号不同
paths: # OAS的核心,必须填的参数,定义了接口的路径和操作
/sort:
get:
parameters:
- $ref: './includes/parameters.yaml#/sort'
components: # 搭建OAS的重复使用的各种模块,这里由于篇幅,就只列两种比较常见的模块
parameters: # 用来定义参数的模块
sort:
name: sort
in: query
schema:
$ref: '#/components/schemas/sortType'
schemas: # 用来定义输入和输出的模块
sortType:
type: string
description: 'The direction of the sort'
enum:
- asc
- desc

简单介绍完OAS编写规范后,下面就简单说说如果编写OAS。编写OAS可以用JSON或者YAML方法,使用任何editor都可以编写。VS Code和WebStorm IDE更是直接有专门插件,帮助更好的设计并编写OAS。下面这个图就是VS Code的OAS编写插件



image.png



此外,OAS社区现在还开放了免费的Swagger Editor Online,可以提供实时一边设计API,一边生成文档。这里甚至还提供一些著名公司开放的APIs,直接把玩这些公司的开放API接口。

image.png



除了直接编写OAS的做法外,其实还可以用专门工具例如SwaggerJSDoc,根据现有项目APIs生成对应的OAS文档。这块在后面API文档会专门详细介绍。

APIs开发

如果你仔细观察上面Swagger Editor Online那个图,会发现这个Editor还附带Generate Code SDK功能。这就是Swagger提供的另一强大利器swagger code generator



image.png



实际上,Swagger code generator工具已经衍生出各种工具。各位小伙伴可以自行去GOOGLE,甚至VS CODE等都有各类插件支持SDK生成简单的基本boiler项目。网上现在还有专门的书,名叫《REST API代码生成指南》,支持多国语言。

其实,无论什么Swagger Code Generator,基本都是根据提供的OAS文档,进行解析成相应的AST Swagger Object,然后对应OAS规范,进行验证。然后根据相应编程语言和环境,就根据主流框架或者设计规范,生成相应的对应API接口。





这里我就专门提一下推荐JS的代码生成器SwaggerJS吧,毕竟现在JS已经前后端都通吃了。无论前后端,只有提供一套相同的OAS文档,大家所遵循的API接口都是统一的。SwaggerJS也是用在Swagger UI里面,用来生成动态可以交互的API文档。后面介绍API文档时候,会有更详细的解释。

APIs文档

APIs文档目的就是让API更好的使用和管理。特别是当项目的API与日俱增,有时候会根据项目新的需求,不断更换迭代。可以说,API文档管理在没有Swagger UI这东西出现的时候,那这是非常痛苦的一件事。当然,这是创建Swagger的初衷。

除了Swagger UI以外,这里还不得不提到这个swagger-jsdoc工具。如果你的现有项目需要创建API文档,你只需要在APIs的注释里,按照OpenAPI Spec,定义好参数。正如下面例子,如果仔细看,会发现参数的定义,其实不就是OAS的YAML文档格式嘛!当然,你也可以注释里,用JSDoc格式写,然后会有配套的JS Doc解释器进行解析。

// Sets up the routes.
module.exports.setup = (app) => {
/**
* @swagger
* /:
* get:
* description: Returns the homepage
* responses:
* 200:
* description: hello world
*/
app.get('/', (req, res) => {
res.send('Hello World!');
});
/**
* @swagger
* /users:
* get:
* description: Returns users
* tags:
* - Users
* produces:
* - application/json
* responses:
* 200:
* description: users
*/
app.get('/users', (req, res) => {
res.json({
username: 'jsmith',
});
});
/**
* @swagger
* /users:
* post:
* description: Returns users
* tags: [Users]
* produces:
* - application/json
* parameters:
* - $ref: '#/parameters/username'
* responses:
* 200:
* description: users
*/
app.post('/users', (req, res) => {
res.json(req.body);
});
};

SwaggerJS Doc把注释的JS Doc和YAML的参数都进行解析成swagger object,然后用swagger parser进行验证,最后生成相应的OAS文档。

APIs互动

上面提到的Swagger UI其实是提供一个专门提供一套前端文档UI和解析OAS文档的功能服务。在服务端提供web客户端,并用swagger client去解析OAS文档,随时生成最新的API来提供实时交互。如下图,只要设计好了OAS文档,用户就可以把玩客户端使用的APIs。

image.png

APIs测试

实际上,有人发现,OAS这种先设计API,然后通过生成API接口的理念,不和POSTMAN API测试理念直接对口吗。





于是便设计出了以下测试流程。说白了,就是POSTMAN已经完全支持OAS规范,可以直接在POSTMAN生成好对应的API,然后在POST定义好测试数据,对接口进行验证。

当然,利用OAS规范和相应的Swagger Parser也可以生成,对应的API接口,然后编写对应的接口测试。

使用OAS的一些坑和心得

上面提到了项目通过注释加swagger jsDoc来自动生成OAS,其实这种做法会遇到不少坑。首先,就是需要手动根据OAS规范,去重复写一遍自己定义好的接口。如果说API设计有不符合OAS规范的,例如有些复杂的接口或者有复用逻辑的,则需要进行代码重构。也就是说搞不好,时间期望会超预期。另外,还有些场景,需要公开暴露一些接口文档,这种情况下,根据需要定义不同的OAS文档。

另外,如果是项目手动设计OAS时候,建议还是根据项目API设计,对OAS进行拆分。这样好处就是,无论项目发展到什么规范,对应的OAS模块都是对应的模块下设计。每次项目运行时候,会动态进行OAS文档拼接并且验证。这次好处不仅有利于管理,并且还可以方便复用。另外,如果项目需要自定义一些参数验证和错误验证,推荐用z-schema对swagger object和数据进行匹配验证。

参考资料

发布于: 2020 年 12 月 02 日阅读数: 84
用户头像

还未添加个人签名 2017.10.30 加入

还未添加个人简介

评论

发布
暂无评论
聊聊OpenAPI Specification(OAS)