本文介绍如何使用Swagger编写API文档。通过阅读本文,你可以:
本文包括对swagger specification(以下译作”规范“)的介绍,如何使用swaager协议编写出功能完整、结构清晰的API文档,以及项目实践中需要注意的问题。
swagger的生态完整,从文档生成、编辑、测试到各种语言的代码自动生成,都有很多开源工具支持。本文中不介绍这些工具的使用。
The World's Most Popular Framework for APIs.
Starting January 1st 2016 the Swagger Specification has been donated(捐赠) to the Open API Initiative (OAI) and is the foundation of the OpenAPI Specification.
Swagger(丝袜哥)给人第一印象就是【最(hen)流(niu)行(bai)】,不懂Swagger咱就out了。它的官方网站是http://swagger.io/。
Swagger是一个简单但功能强大的API表达工具。它具有地球上最大的API工具生态系统,数以千计的开发人员,使用几乎所有的现代编程语言,都在支持和使用Swagger。使用Swagger生成API,我们可以得到交互式文档,自动生成代码的SDK以及API的发现特性等。
现在,Swagger已经帮助包括Apigee, Getty图像, Intuit, LivingSocial, McKesson, 微软, Morningstar和PayPal等世界知名企业建立起了一套基于RESTful API的完美服务系统。
2.0版本已经发布,Swagger变得更加强大。值得感激的是,Swagger的源码100%开源在github。
OpenAPI规范是Linux基金会的一个项目,试图通过定义一种用来描述API格式或API定义的语言,来规范RESTful服务开发过程。OpenAPI规范帮助我们描述一个API的基本信息,比如:
目前V2.0版本的OpenAPI规范(也就是SwaggerV2.0规范)已经发布并开源在github上。该文档写的非常好,结构清晰,方便随时查阅。关于规范的学习和理解,本文最后还有个彩蛋。
1.4.1 语言:JSON vs YAML
我们可以选择使用JSON或者YAML的语言格式来编写API文档。但是个人建议使用YAML来写,原因是它更简单。一图胜千言,先看用JSON写的文档:
-
{
-
"swagger":
"2.0",
-
"info": {
-
"version":
"1.0.0",
-
"title":
"Simple API",
-
"description":
"A simple API to learn how to write OpenAPI Specification"
-
},
-
"schemes": [
-
"https"
-
],
-
"host":
"simple.api",
-
"basePath":
"/openapi101",
-
"paths": {
-
"/persons": {
-
"get": {
-
"summary":
"Gets some persons",
-
"description":
"Returns a list containing all persons.",
-
"responses": {
-
"200": {
-
"description":
"A list of Person",
-
"schema": {
-
"type":
"array",
-
"items": {
-
"properties": {
-
"firstName": {
-
"type":
"string"
-
},
-
"lastName": {
-
"type":
"string"
-
},
-
"username": {
-
"type":
"string"
-
}
-
}
-
}
-
}
-
}
-
}
-
}
-
}
-
}
-
}
再来看看同一份API文档的YAML实现:
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons.
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
type:
array
-
items:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
对于普通人来说,似乎用YAML更能够简化书写和阅读。这里我们并没有非此即彼的选择问题,因为:
所以,用自己喜欢的方式书写即可。(后面的示例文档也都是用YAML来写的。强烈推荐使用YAML。)
1.4.2 编辑器
编写API文档,其实我们只是在写一个简单的文本文件。我们可以用任何最普通的文档编辑器来写。但是为了提高效率,还是建议使用专业的编辑工具。众多工具中,最好的选择是Swagger Editor,它能够提供语法高亮、自动完成、即时预览等功能,非常强大。
左边编辑API文档,右边实时预览。下面这张动图展示编辑提升功能:
我们可以使用在线版本来编辑,也可以非常简单的本地部署,更多细节请参考另一篇文档Swagger环境搭建.md以及Swagger Editor开源仓库上的说明。
这一章主要介绍API的基本组成部分,包括提供给API消费者(所有可能访问API的个体,下简称“消费者”)的的不同HTTP请求方法、路径,请求和消息体中的参数,以及返回给消费者的不同HTTP状态及响应消息体。
我们从一个最简单(几乎没有东西)的API文档开始:
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths: {}
这个文档的内容分成四部分,下面分别来说明。
2.1.1 OpenAPI规范的版本号
首先我们要通过一个swagger
属性来声明OpenAPI规范的版本。
swagger: "2.0"
你没看错,是swagger
,上面已经介绍了,OpenAPI规范是基于Swagger的,在未来的版本中,这个属性可能会换成别的。 目前这个属性的值,暂时只能填写为2.0
。
2.1.2 API描述信息
然后我们需要说明一下API文档的相关信息,比如API文档版本(注意不同于上面的规范版本)、API文档名称已经可选的描述信息。
-
info:
-
version:
1.0.
0
-
title: Simple API
-
description: A simple API
to learn how
to
write OpenAPI Specification
2.1.3 API的URL
作为web API,一个很重要的信息就是用来给消费者使用的根URL
,可以用协议(http或者https)、主机名、根路径来描述:
schemes: - https host: simple.api basePath: /openapi101
这这个例子中,消费者把https://simple.api/open101
作为根节点来访问各种API。因为和具体环境有关,不涉及API描述的根本内容,所以这部分信息是可选的。
2.1.4 API的操作(operation)
这个例子中,我们没有写API的操作,用一个YAML的空对象{}
先占个位置。
如果我们要展示一组用户信息,可以这样描述:
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons.
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
type:
array
-
items:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
2.2.1 添加一个路径
(path)
我们添加一个/persons
的路径
,用来访问一组用户信息:
paths: /persons:
2.2.2 在路径中添加一个HTTP方法
在每个路径
中,我们可以添加任意的HTTP动词来操作所需要的资源。
比如需要展示一组用户信息,我们可以在/persons
路径中添加get
方法,同时还可以填写一些简单的描述信息(summary)或者说明该方法的一段长篇大论(description)。
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons.
这样一来,我们调 get https://simple.api/open101/persons方法就能获取一个用户信息列表了。
2.2.3 定义响应
(response)类型
对于每个方法(或操作),我们都可以在响应
(responses)中添加任意的HTTP状态码(比如200 OK 或者 404 Not Found等)。这个例子中我们添加上200
的响应:
-
responses:
-
200:
-
description: A list
of Person
2.2.4 定义响应内容
get /persons这个接口返回一组用户信息,我们通过响应消息中的模式
(schema)属性来描述清楚具体的返回内容。
一组用户信息就是一个用户信息对象的数组
(array),每一个数组元素则是一个用户信息对象
(object),该对象包含三个string类型的属性:姓氏
、名字
、用户名
,其中用户名
必须提供(required)。
-
schema:
-
type:
array
-
items:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
请求参数
(query parameters)用户太多,我们不想一股脑全部输出出来。这个时候,分页输出是个不错的选择,我们可以通过添加请求参数来实现。
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
#START############################################################################
-
parameters:
-
- name: pageSize
-
in: query
-
description: Number
of persons returned
-
type:
integer
-
- name: pageNumber
-
in: query
-
description: Page number
-
type:
integer
-
# END ############################################################################
-
responses:
-
200:
-
description: A list
of Person
-
schema:
-
type: array
-
items:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
2.3.1 在get方法中增加请求参数
首先我们在 get 方法中增加一个参数
属性:
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a
list containing all persons. The
list supports paging.
-
#START############################################################################
-
parameters:
-
# END ############################################################################
2.3.2 添加分页参数
在参数列表中,我们添加两个名字(name)分别叫做pageSize
和pageNumber
的整型(integer)参数,并作简单描述:
-
parameters:
-
#START############################################################################
-
-
name: pageSize
-
in: query
-
description: Number
of persons returned
-
type: integer
-
-
name: pageNumber
-
in: query
-
description: Page number
-
type: integer
-
#
END ##############################################################################
-
responses:
这样一来,消费者就可以通过 get /persons?pageSize=20&pageNumber=2 来访问第2页的用户信息(不超过20条)了。
路径参数
(path parameter)有时候我们想要根据用户名来查找用户信息,这时我们需要增加一个接口操作,比如可以添加一个类似 /persons/{username} 的操作来获取用户信息。注意,{username} 是在请求路径中的参数。
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
parameters:
-
- name: pageSize
-
in: query
-
description: Number of persons returned
-
type: integer
-
- name: pageNumber
-
in: query
-
description: Page number
-
type: integer
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
type:
array
-
items:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
-
#START############################################################################
-
/persons/{username}:
-
get:
-
summary: Gets a person
-
description: Returns a single person
for its username
-
parameters:
-
- name: username
-
in: path
-
required:
true
-
description: The person
's username
-
type:
string
-
responses:
-
200:
-
description: A Person
-
schema:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
404:
-
description: The Person does
not exists.
-
#
END ############################################################################
2.4.1 添加一个 get /persons/{username} 操作
首先我们在 /persons 路径后面,增加一个 /persons/{username} 的路径,并定义一个 get (操作)方法。
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
username:
-
type:
string
-
#START############################################################################
-
/persons/{username}:
-
get:
-
summary: Gets a person
-
description: Returns a single person
for its username
-
# END ############################################################################
2.4.2 定义路径参数 username
因为 {username} 是路径参数,我们需要先像请求参数一样将它添加到 parameters 属性中,注意名称应该同上面大括号( { } ) 里面的名称一致。并通过 in
这个属性,来表示它是一个路径(path)参数。
-
parameters:
-
- name: username
-
in: path
-
required:
true
-
description: The person
's username
-
type:
string
定义路径参数时很容易出现的问题就是忘记:required: true
,Swagger的自动完成功能中没有包含这个属性定义。 如果没有写 require 属性,默认值是 false,也就是说 username 参数时可选的。可事实上,作为路径参数,它是必需的。
2.4.3 定义响应消息
别忘了获取单个用户信息也需要填写 200 响应消息,响应消息体的内容就是之前描述过的用户信息(用户信息列表中的一个元素):
-
responses:
-
200:
-
description: A Person
-
schema:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
当然,API的提供者会对 username 进行校验,如果查无此人,应该返回 404 的异常状态。所以我们再加上 404 状态的响应:
-
404:
-
description: The Person does
not exists.
消息体参数
(body parameter)当我们需要添加一个用户信息时,我们需要一个能够提供 post /persons 的API操作。
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
parameters:
-
- name: pageSize
-
in: query
-
description: Number of persons returned
-
type: integer
-
- name: pageNumber
-
in: query
-
description: Page number
-
type: integer
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
type:
array
-
items:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
#START############################################################################
-
post:
-
summary: Creates a person
-
description: Adds a
new person
to the persons list.
-
parameters:
-
- name: person
-
in: body
-
description: The person
to create.
-
schema:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
responses:
-
204:
-
description: Persons succesfully created.
-
400:
-
description: Persons couldn
't have been created.
-
#
END ############################################################################
-
/persons/{username}:
-
get:
-
summary: Gets a person
-
description: Returns a single person
for its username.
-
parameters:
-
- name: username
-
in: path
-
required:
true
-
description: The person
's username
-
type:
string
-
responses:
-
200:
-
description: A Person
-
schema:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
404:
-
description: The Person does
not exists.
2.5.1 添加一个 post /persons 操作
首先在 /persons 路径下廷加一个 post 操作:
paths: /persons:
-
post:
-
summary: Creates a person
-
description: Adds a
new person
to the persons list.
2.5.2 定义消息体参数
接下来我们给 post 方法添加参数,通过 in
属性显式说明参数是在 body 中的。参数的定义参考 get /persons/{username} 的 200 响应消息体参数,也就是包含用户的姓氏、名字、用户名。
-
parameters:
-
-
name: person
-
in: body
-
description: The person
to create.
-
schema:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
2.5.3 定义响应消息
最后不要忘记定义 post 操作的响应消息。
-
responses:
-
204:
-
description: Persons succesfully created.
-
400:
-
description: Persons couldn
't have been created.
现在我们已经学会了编写API文档的基本方法。不过上面的例子中存在一些重复,这对于程序员的嗅觉来说,就是代码的“坏味道”。这一章我们一起学习如何通过抽取可重用的定义(definitions)来简化API文档。
我们认真观察第2章最后输出的API文档,很容易发现 Person 的定义出现了三次,非常的不 DRY
☹。
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
parameters:
-
- name: pageSize
-
in: query
-
description: Number of persons returned
-
type: integer
-
- name: pageNumber
-
in: query
-
description: Page number
-
type: integer
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
type:
array
-
items:
-
#START 第
1次定义###################################################################
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
#
END 第
1次定义###################################################################
-
post:
-
summary: Creates a person
-
description: Adds a
new person
to the persons list.
-
parameters:
-
- name: person
-
in: body
-
description: The person
to create.
-
schema:
-
#START 第
2次定义###################################################################
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
#
END 第
2次定义###################################################################
-
responses:
-
204:
-
description: Persons succesfully created.
-
400:
-
description: Persons couldn
't have been created.
-
/persons/{username}:
-
get:
-
summary: Gets a person
-
description: Returns a single person
for its username.
-
parameters:
-
- name: username
-
in: path
-
required:
true
-
description: The person
's username
-
type:
string
-
responses:
-
200:
-
description: A Person
-
schema:
-
#START 第
3次定义###################################################################
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
#
END 第
3次定义###################################################################
-
404:
-
description: The Person does
not exists.
现在,我们通过可重用的定义
(definition)来重构这个文档:
-
swagger:
"2.0"
-
-
info:
-
version: 1.0.0
-
title: Simple API
-
description: A simple API to learn how to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
parameters:
-
- name: pageSize
-
in: query
-
description: Number of persons returned
-
type:
integer
-
- name: pageNumber
-
in: query
-
description: Page number
-
type:
integer
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
#START############################################################################
-
$ref:
"#/definitions/Persons"
-
# END ############################################################################
-
post:
-
summary: Creates a person
-
description: Adds a new person to the persons list.
-
parameters:
-
- name: person
-
in: body
-
description: The person to create.
-
schema:
-
#START############################################################################
-
$ref:
"#/definitions/Person"
-
# END ############################################################################
-
responses:
-
204:
-
description: Persons succesfully created.
-
400:
-
description: Persons couldn
't have been created.
-
/persons/{username}:
-
get:
-
summary: Gets a person
-
description: Returns a single person for its username.
-
parameters:
-
- name: username
-
in: path
-
required: true
-
description: The person's username
-
type: string
-
responses:
-
200:
-
description: A Person
-
schema:
-
#START############################################################################
-
$ref:
"#/definitions/Person"
-
# END ############################################################################
-
404:
-
description: The Person does not exists.
-
-
#START 新增定义####################################################################
-
definitions:
-
Person:
-
required:
-
- username
-
properties:
-
firstName:
-
type: string
-
lastName:
-
type: string
-
username:
-
type: string
-
Persons:
-
type: array
-
items:
-
$ref:
"#/definitions/Person"
-
# END 新增定义####################################################################
文档简化了很多。这得益于OpenAPI规范中关于定义(definition)的章节中允许我们“一处定义,处处使用”。
3.1.1 添加定义
(definitions)项
我们首先在API文档的尾部添加一个定义
(definitions)项(其实它也可以放在文档的任意位置,只不过大家习惯放在文档末尾):
-
404:
-
description: The Person does
not exists.
-
#START############################################################################
-
definitions:
-
# END ############################################################################
3.1.2 增加一个可重用的(对象)定义
然后我们增加一个 Person 对象的定义:
-
definitions:
-
#START############################################################################
-
Person:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
#
END ############################################################################
3.1.3 引用一个定义
来增加另一个定义
在定义项中,我们可以立即引用刚才定义好的 Person 来增加另一个定义
,Persons。Persons 是一个 Person 对象的数组。与之前直接定义的不同之处是,我们增加了一个引用
(reference)属性,也就是 $ref来引用 Person 。
-
Persons:
-
type:
array
-
items:
-
$ref:
"#/definitions/Person"
3.1.4 在响应消息中使用定义
一旦定义好了 Person ,我们可以把原来在响应消息中相应的定义字段替换掉。
3.1.4.1 get/persons
原来:
-
responses:
-
200:
-
description: A list
of Person
-
schema:
-
type:
array
-
items:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
现在:
-
responses:
-
200:
-
description: A
list of Person
-
schema:
-
$ref:
"#/definitions/Persons"
3.1.4.2 get/persons/{username}
原来:
-
responses:
-
200:
-
description: A Person
-
schema:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
现在:
-
responses:
-
200:
-
description: A Person
-
schema:
-
$ref:
"#/definitions/Person"
3.1.5 在参数中使用定义
不仅仅在消息中可以使用定义
,在参数中也可以使用。
3.1.5.1 post /persons
原来:
-
post:
-
summary: Creates a person
-
description: Adds a new person
to the persons list.
-
parameters:
-
-
name: person
-
in: body
-
description: The person
to create.
-
schema:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
现在:
-
post:
-
summary: Creates a person
-
description: Adds a
new person
to the persons list.
-
parameters:
-
- name: person
-
in: body
-
description: The person
to create.
-
schema:
-
$ref:
"#/definitions/Person"
我们看到了引用
($ref)的作用,接下来我们再把它用到响应消息的定义中:
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
parameters:
-
- name: pageSize
-
in: query
-
description: Number of persons returned
-
type: integer
-
- name: pageNumber
-
in: query
-
description: Page number
-
type: integer
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
$ref:
"#/definitions/Persons"
-
#START############################################################################
-
500:
-
$ref:
"#/responses/Standard500ErrorResponse"
-
#
END ############################################################################
-
post:
-
summary: Creates a person
-
description: Adds a
new person
to the persons list.
-
parameters:
-
- name: person
-
in: body
-
description: The person
to create.
-
schema:
-
$ref:
"#/definitions/Person"
-
responses:
-
204:
-
description: Persons succesfully created.
-
400:
-
description: Persons couldn
't have been created.
-
#START############################################################################
-
500:
-
$ref:
"#/responses/Standard500ErrorResponse"
-
#
END ############################################################################
-
-
/persons/{username}:
-
get:
-
summary: Gets a person
-
description: Returns a single person
for its username.
-
parameters:
-
- name: username
-
in: path
-
required:
true
-
description: The person
's username
-
type:
string
-
responses:
-
200:
-
description: A Person
-
schema:
-
$ref:
"#/definitions/Person"
-
404:
-
description: The Person does
not exists.
-
#START############################################################################
-
500:
-
$ref:
"#/responses/Standard500ErrorResponse"
-
#
END ############################################################################
-
-
definitions:
-
Person:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
Persons:
-
type:
array
-
items:
-
$ref:
"#/definitions/Person"
-
#START############################################################################
-
Error:
-
properties:
-
code:
-
type:
string
-
message:
-
type:
string
-
-
responses:
-
Standard500ErrorResponse:
-
description: An unexpected
error occured.
-
schema:
-
$ref:
"#/definitions/Error"
-
#
END ############################################################################
3.2.1 定义可重用的HTTP 500 响应
发生HTTP 500错误时,假如我们希望每一个API操作都返回一个带有错误码(error code)和描述信息(message)的响应,我们可以这样做:
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
parameters:
-
- name: pageSize
-
in: query
-
description: Number of persons returned
-
type: integer
-
- name: pageNumber
-
in: query
-
description: Page number
-
type: integer
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
$ref:
"#/definitions/Persons"
-
#START############################################################################
-
500:
-
description: An unexpected
error occured.
-
schema:
-
properties:
-
code:
-
type:
string
-
message:
-
type:
string
-
#
END ############################################################################
-
post:
-
summary: Creates a person
-
description: Adds a
new person
to the persons list.
-
parameters:
-
- name: person
-
in: body
-
description: The person
to create.
-
schema:
-
$ref:
"#/definitions/Person"
-
responses:
-
204:
-
description: Persons succesfully created.
-
400:
-
description: Persons couldn
't have been created.
-
#START############################################################################
-
500:
-
description: An unexpected
error occured.
-
schema:
-
properties:
-
code:
-
type:
string
-
message:
-
type:
string
-
#
END ############################################################################
-
-
/persons/{username}:
-
get:
-
summary: Gets a person
-
description: Returns a single person
for its username.
-
parameters:
-
- name: username
-
in: path
-
required:
true
-
description: The person
's username
-
type:
string
-
responses:
-
200:
-
description: A Person
-
schema:
-
$ref:
"#/definitions/Person"
-
404:
-
description: The Person does
not exists.
-
#START############################################################################
-
500:
-
description: An unexpected
error occured.
-
schema:
-
properties:
-
code:
-
type:
string
-
message:
-
type:
string
-
#
END ############################################################################
3.2.2 增加一个Error定义
按照“一处定义、处处引用”的原则,我们可以在定义项中增加 Error 的定义:
-
definitions:
-
Person:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
Persons:
-
type: array
-
items:
-
$ref:
"#/definitions/Person"
-
#START############################################################################
-
Error:
-
properties:
-
code:
-
type:
string
-
message:
-
type:
string
-
# END ############################################################################
而且我们也学会了使用引用
($ref),所以我们可以这样写:
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
parameters:
-
- name: pageSize
-
in: query
-
description: Number of persons returned
-
type: integer
-
- name: pageNumber
-
in: query
-
description: Page number
-
type: integer
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
$ref:
"#/definitions/Persons"
-
500:
-
description: An unexpected
error occured.
-
schema:
-
#START############################################################################
-
$ref:
"#/definitions/Error"
-
#
END ############################################################################
-
post:
-
summary: Creates a person
-
description: Adds a
new person
to the persons list.
-
parameters:
-
- name: person
-
in: body
-
description: The person
to create.
-
schema:
-
$ref:
"#/definitions/Person"
-
responses:
-
204:
-
description: Persons succesfully created.
-
400:
-
description: Persons couldn
't have been created.
-
500:
-
description: An unexpected
error occured.
-
schema:
-
#START############################################################################
-
$ref:
"#/definitions/Error"
-
#
END ############################################################################
-
/persons/{username}:
-
get:
-
summary: Gets a person
-
description: Returns a single person
for its username.
-
parameters:
-
- name: username
-
in: path
-
required:
true
-
description: The person
's username
-
type:
string
-
responses:
-
200:
-
description: A Person
-
schema:
-
$ref:
"#/definitions/Person"
-
404:
-
description: The Person does
not exists.
-
500:
-
description: An unexpected
error occured.
-
schema:
-
#START############################################################################
-
$ref:
"#/definitions/Error"
-
#
END ############################################################################
3.2.3 定义一个可重用的响应消息
上面的文档中,还是有一些重复的内容。我们可以根据OpenAPI规范中的responses章节的描述,通过定义一个可重用的响应消息,来进一步简化文档。
-
definitions:
-
Person:
-
required:
-
- username
-
properties:
-
firstName:
-
type:
string
-
lastName:
-
type:
string
-
username:
-
type:
string
-
Persons:
-
type: array
-
items:
-
$ref:
"#/definitions/Person"
-
Error:
-
properties:
-
code:
-
type:
string
-
message:
-
type:
string
-
#START############################################################################
-
responses:
-
Standard500ErrorResponse:
-
description: An unexpected error occured.
-
schema:
-
$ref:
"#/definitions/Error"
-
# END ############################################################################
注意:响应消息中引用了 Error 的定义。
3.2.4 使用已定义的响应消息
我们还是通过引用
($ref)来使用一个已经定义好的响应消息,比如:
3.2.4.1 get /users
-
responses:
-
200:
-
description: A
list of Person
-
schema:
-
$ref:
"#/definitions/Persons"
-
#START############################################################################
-
500:
-
$ref:
"#/responses/Standard500ErrorResponse"
-
# END ############################################################################
3.2.4.2 post/users
-
responses:
-
204:
-
description: Persons succesfully created.
-
400:
-
description: Persons couldn
't have been created.
-
#START############################################################################
-
500:
-
$ref:
"#/responses/Standard500ErrorResponse"
-
# END ############################################################################
3.2.4.3 get/users/{username}
-
responses:
-
200:
-
description: A Person
-
schema:
-
$ref:
"#/definitions/Person"
-
404:
-
description: The Person does
not exists.
-
#START############################################################################
-
500:
-
$ref:
"#/responses/Standard500ErrorResponse"
-
# END ############################################################################
类似数据模型、响应消息的简化,参数定义的简化也很容易。
-
swagger:
"2.0"
-
-
info:
-
version:
1.0
.0
-
title: Simple API
-
description: A simple API
to learn how
to write OpenAPI Specification
-
-
schemes:
-
- https
-
host: simple.api
-
basePath: /openapi101
-
-
paths:
-
/persons:
-
get:
-
summary: Gets some persons
-
description: Returns a list containing all persons. The list supports paging.
-
#START############################################################################
-
parameters:
-
- $ref:
"#/parameters/pageSize"
-
- $ref:
"#/parameters/pageNumber"
-
#
END ############################################################################
-
responses:
-
200:
-
description: A list of Person
-
schema:
-
$ref:
"#/definitions/Persons"
-
500:
-
$ref:
"#/responses/Standard500ErrorResponse"
-
post:
-
summary: Creates a person
-
description: Adds a
new person
to the persons list.
-
parameters:
-
- name: person
-
in: body
-
description: The person
to create.
-
schema:
-