Introduction to OpenAPI

Introduction to OpenAPI

随着 RESTful API 在 WEB 应用程序界的大行其道,如何规范、优雅、易懂地设计和描述一套 RESTful API 成为了一个广泛的问题。在探索的过程中,开源开发者们提供了许多可通用的解决方案,Swagger 的 OpenAPI 便是其中之一。本文将带你快速上手 OpenAPI,对于更细节、权威的说明,请访问其官方文档

为什么要使用 OpenAPI?

OpenAPI 作为一种 REST API 描述的规范,它允许使用者完整地描述任意一种 REST API 实体,这包括:

  • 端点(如/user)与方法(GET)
  • 操作参数和输出
  • 权限认证
  • 联系方式、证书等

这些 API 的描述可以以 YAML 或 JSON 的格式写成,方便学习并且具有高度可读性。在完成 API 文档的编写后,我们通常可以选用 Swagger UI 或 Swagger Editor 生成交互式的 API 文档。其中,我们将在本文主要谈到后者。Swagger Editor是一个基于浏览器的免费工具,您只需要在左侧写入满足 OpenAPI 规范的文档,在右侧即可得到一个交互式的图形化 API 文档。成品效果图如下:

基本结构

满足 OpenAPI 规范的文档可以用 YAML 或者 JSON 格式写就,本文推荐您使用前者,因其拥有更广泛的教程和完善的社区,但后者也能得到完整的支持。OpenAPI 目前的最新版为 3.0,使用老旧的 2.0 或更早版本可能带来语法混乱、功能残缺等问题,我们推荐您使用最新版来避免遭遇这些困扰。一个符合 OpenAPI 3.0 规范的文档大约如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
openapi: 3.0.0
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
- url: http://staging-api.example.com
description: Optional server description, e.g. Internal staging server for testing
paths:
/users:
get:
summary: Returns a list of users.
description: Optional extended description in CommonMark or HTML.
responses:
'200': # status code
description: A JSON array of user names
content:
application/json:
schema:
type: array
items:
type: string

注意:所有关键字均为大小写敏感的

您可以注意到,上面的示例文档实际上包含有四个板块:openapiinfoserverspaths,他们分别指明了 OpenAPI 版本信息(解释器将根据此选择合适版本的语法尝试进行解析),文档源信息(这包含标题、描述和 API 版本号),服务器(在其中可以填入一个或多个服务器地址,也就是之后端点相对路径的基路径(base path),并包含他们的描述)和端点(endpoint)路径(均为相对路径)。前面三者是简单明了的,而后者则是我们需要描述的主体,对于 REST API 的实际定义均在此标签下进行。

API 的描述

端点和方法(Endpoints & Methods)

paths 标签的直接子标签的标签名即为端点名。如下,我们就定义了/user/weapon 两个端点:

1
2
3
4
5
6
...
paths:
/user:
...
/weapon:
...

而根据 REST 设计风格我们知道,对于一个完整的 API,我们除了需要给出端点路径外,还需要明确方法。在 OpenAPI 3.0 中,只需要在端点的直接子标签内写入方法即可:

1
2
3
4
5
...
paths:
/user:
get:
...

此时方法和端点共同构成了一个结构完整的 API,会以一个可伸缩的 Tab 的形式显示在 Swagger Editor 右侧的渲染边栏内,但你会惊奇地发现,里面还什么都没有。因为这并不是结束,我们还需要给定 API 的传入参数、返回内容和格式。如果你足够贴心,还能为开发人员们留下几段以供参考的的样例。

传入参数(Parameters)与请求体(Request Body)

我们假设您已经对 HTTP 协议有充分的认识。您应该知道,一般的 HTTP 方法使用参数传递输入信息(指 query 模式,以字符串形式),而 POST 方法允许通过请求体传递输入内容(以二进制形式)。在 OpenAPI 里,两者的语法也略有不同。对于传入参数,事实上有四种可选的模式:pathqueryheaderscookies,他们分别是通过 /endpoint/{parameter}/endpoint?parameter=value 格式的 URL,HTTP 请求头和 cookies 字段来实现的信息传递。更常用的前两者的 OpenAPI 写法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
paths:
/user/{userId}:
get:
summary: Some summary of the whole api
parameters:
- name: userId
in: path
required: true
description: ...
schema:
type: integer
format: int64
minimum: 1
- name: queryString
in: query
required: true
description: ...
schema:
type: string
...

在这里我们定义了两个参数,分别是 path 模式的 userIdquery 模式的 queryString,在他们的子标签中,schema 用于描述变量的“模式”,在其中,变量的类型、格式以及其他约束将会被描述。另外,你可以通过 required: true 来将一个参数设置为必选参数。

requestBody 与之类似而又不同,我们直接看语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
...
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
userId:
type: integer
requestString:
type: string
...

requestBody 中,我们通过 content 描述其内容,并通过 application/json 一类的标签描述内容的 MIME 类型。由于内容本身就是一个变量,因而我们需要先对其的模式进行描述。在这里我们使用了 type: object,这表示它是一个 JSON Object,从而允许我们使用 properties 标签对其内的键值对进行描述,这点就类似于 parameters 了。需要注意的是,这些键值对并不支持 required 标签。

返回内容(Responses)

描述完输入(参数),自然也就该说说输出(响应)了。对于每个 Method,我们都需要定义一些响应来指导用户的使用,依旧先来看看例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
paths:
/user/{userId}:
get:
summary: Returns a user by ID.
parameters:
- name: userId
in: path
required: true
description: The ID of the user to return.
schema:
type: integer
format: int64
minimum: 1
responses:
'200':
description: A user object.
content:
application/json:
schema:
type: object
properties:
id:
type: integer
format: int64
example: 4
name:
type: string
example: Jessica Smith
'400':
description: The specified user ID is invalid (not a number).
'404':
description: A user with the specified ID was not found.

可以看到,在 responses 标签下,我们首先需要列出我们可能返回的 HTTP 状态码,然后在该子标签下通过类似 requestBody 下的格式进行描述(二者本质上都一样,是二进制的数据串)。

样例(Examples)

由于 Swagger Editor 设置上的限制,我们不能在 OpenAPI 约束的条件下完成多样例的撰写和展示,一个可选的替代方案是在 content 的同级标签下增加一个 examples 标签,并以如下格式撰写内容:

1
2
3
4
5
6
examples:
YourTitle:
key1: value1
key2:
key3: value3
key4: value4

Swagger 会将其转换为 JSON Object 格式并展示在 Responses 栏中。

更进一步

以上内容仅仅只是 OpenAPI 语法的入门,还有很多实用的特性(如复用 schema 等)等待你的发现。如果您想要进一步了解,可以通过高质量的官方文档来进行学习。谢谢您的阅读。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×