当我们在检索、更新或删除自行车资源时,需要通过路径指定要操作的资源,如下所示:
GET /bikes/{bikeId}
PUT /bikes/{bikeId}
DELETE /bikes/{bikeId}
可以看到,路径中包含了一个路径参数{bikeId}
,使得 /bikes/{bikeId}
成为一个可变路径。换句话说,bikeId
(自行车标识)取不同的值,路径指向的资源就不同。但是,只要bikeId
的值一定,在执行检索、更新或删除操作时,返回的自行车信息就是同一个资源的。
下面,我们使用 OpenAPI 规范,对检索和删除操作进行描述,看看能否发现一些问题。
检索自行车
下面是检索自行车的示例代码。
/bikes/{bikeId}:
description: 自行车信息。
get:
summary: 检索自行车。
parameters:
- name: bikeId
in: path
required: true
description: 自行车标识
schema:
type: string
responses:
"200":
description: 对应标识的自行车信息
删除自行车
下面是删除自行车的示例代码。
/bikes/{bikeId}:
description: 自行车信息。
delete:
summary: 删除自行车。
description: 删除一个指定的自行车。
parameters:
- name: bikeId
in: path
required: true
description: 自行车标识
schema:
type: string
responses:
"200":
description: 已删除的自行车信息
发现问题
通过比较上面两个操作的描述信息,我们可以很容易发现,路径参数的描述信息是相同的。
parameters:
- name: bikeId
in: path
required: true
description: 自行车标识
schema:
type: string
不要重复发明轮子,那该如何处理呢?使用组件。
参数组件
在组件集合属性中,不仅可以定义可重用的 schema
,也可以定义可重用的参数。
components:
parameters:
bikeId:
name: bikeId
in: path
required: true
description: 自行车标识
schema:
type: string
引用参数
接下来,在检索自行车
和删除自行车
时,我们就可以引用 bikeId
路径参数了。
paths:
/bikes:
[...]
/bikes/{bikeId}:
get:
parameters:
- $ref: #/components/parameters/bikeId
[...]
delete:
parameters:
- $ref: #/components/parameters/bikeId
[...]
还有问题
你一定又发现重复的数据描述了。下面的描述信息出现了两次。
- $ref: #/components/parameters/bikeId
如果考虑到更新自行车
时,也会使用相同的描述,这一行信息会出现 3 次。能否消除这种重复的情况呢?
资源参数
路径参数 bikeId
被定义了一次,在检索和删除两个操作中进行了引用。需要明确的是,路径参数 bikeId
不是操作层级的参数,而是资源层级的参数。因此,我们可以在资源属性下面进行定义,这样,就可以省去在每个操作中进行定义。
components:
parameters:
bikeId:
[...]
paths:
/bikes/{bikeId}:
parameters:
- $ref: #/components/parameters/bikeId
get:
[...]
delete:
[...]
put:
[...]
这样看起来,是不是更加完美了。
小结
我们使用组件对象,定义了路径参数,避免在多个资源操作中进行描述;然后,我们路径参数的引用,放到了资源层级的参数中,不必在每个操作中重复引用。经过两次重构,文档变得更加简洁,清晰。