描述请求正文
请求正文通常用于“创建”和“更新”操作(POST、PUT、PATCH)。例如,当使用 POST 或 PUT 创建资源时,请求正文通常包含要创建资源的表示。OpenAPI 3.0 提供了 requestBody 关键字来描述请求正文。
与 OpenAPI 2.0 的区别
如果您之前使用过 OpenAPI 2.0,以下是帮助您开始使用 OpenAPI 3.0 的变更摘要:
- Body 和 form 参数被
requestBody替换。 - 操作现在可以同时消费表单数据和其他媒体类型,例如 JSON。
consumes数组被requestBody.content映射取代,后者将媒体类型映射到其模式。- 模式可以根据媒体类型而异。
anyOf和oneOf可用于指定备选模式。- 表单数据现在可以包含对象,并且您可以指定对象和数组的序列化策略。
- 根据 RFC 7231,GET、DELETE 和 HEAD 不再允许包含请求正文,因为它们没有定义语义。
requestBody、content 和媒体类型
与 OpenAPI 2.0 中使用 body 和 formData 参数定义请求正文不同,OpenAPI 3.0 使用 requestBody 关键字来区分负载与参数(如查询字符串)。requestBody 更灵活,它允许您消费不同的媒体类型,例如 JSON、XML、表单数据、纯文本等,并为不同的媒体类型使用不同的模式。requestBody 由 content 对象、一个可选的 Markdown 格式的 description 以及一个可选的 required 标志(默认为 false)组成。content 列出了操作所消费的媒体类型(例如 application/json)并为每种媒体类型指定了 schema。请求正文默认是可选的。要将正文标记为必需,请使用 required: true。
1paths:2 /pets:3 post:4 summary: Add a new pet5
6 requestBody:7 description: Optional description in *Markdown*8 required: true9 content:10 application/json:11 schema:12 $ref: "#/components/schemas/Pet"13 application/xml:14 schema:15 $ref: "#/components/schemas/Pet"16 application/x-www-form-urlencoded:17 schema:18 $ref: "#/components/schemas/PetForm"19 text/plain:20 schema:21 type: string22
23 responses:24 "201":25 description: Createdcontent 允许使用通配符媒体类型。例如,image/* 表示所有图像类型;*/* 表示所有类型,功能上等同于 application/octet-stream。在解释规范时,特定媒体类型优先于通配符媒体类型,例如 image/png > image/* > */*。
1paths:2 /avatar:3 put:4 summary: Upload an avatar5 requestBody:6 content:7 image/*: # Can be image/png, image/svg, image/gif, etc.8 schema:9 type: string10 format: binaryanyOf, oneOf
OpenAPI 3.0 支持 anyOf 和 oneOf,因此您可以为请求正文指定备选模式。
1requestBody:2 description: A JSON object containing pet information3 content:4 application/json:5 schema:6 oneOf:7 - $ref: "#/components/schemas/Cat"8 - $ref: "#/components/schemas/Dog"9 - $ref: "#/components/schemas/Hamster"文件上传
请求正文示例
请求正文可以包含一个 example 或多个 examples。example 和 examples 是 requestBody.content.<media-type> 对象的属性。如果提供了这些示例,它们将覆盖模式提供的示例。这很有用,例如,如果请求和响应使用相同的模式,但您想要有不同的示例。example 允许单个内联示例
1requestBody:2 content:3 application/json:4 schema:5 $ref: "#/components/schemas/Pet"6 example:7 name: Fluffy8 petType: dogexamples(复数)更灵活——您可以有一个内联示例、一个 $ref 引用,或指向包含有效负载示例的外部 URL。每个示例还可以包含可选的 summary 和 description 用于文档目的。
1requestBody:2 content:3 application/json:4 schema:5 $ref: '#/components/schemas/Pet'6 examples:7
8 dog: # <--- example name9 summary: An example of a dog10 value:11 # vv Actual payload goes here vv12 name: Fluffy13 petType: dog14
15 cat: # <--- example name16 summary: An example of a cat17 externalValue: http://api.example.com/examples/cat.json # cat.json contains {"name": "Tiger", "petType": "cat"}18
19 hamster: # <--- example name20 $ref: '#/components/examples/hamster'21
22 components:23 examples:24 hamster: # <--- example name25 summary: An example of a hamster26 value:27 # vv Actual payload goes here vv28 name: Ginger29 petType: hamster有关更多信息,请参阅添加示例。
可复用正文
您可以将请求正文定义放在全局 components.requestBodies 部分,并在其他地方通过 $ref 引用它们。如果多个操作具有相同的请求正文,这会很方便——通过这种方式您可以轻松重用相同的定义。
1paths:2 /pets:3 post:4 summary: Add a new pet5 requestBody:6 $ref: '#/components/requestBodies/PetBody'7
8 /pets/{petId}9 put:10 summary: Update a pet11 parameters: [ ... ]12 requestBody:13 $ref: '#/components/requestBodies/PetBody'14
15components:16 requestBodies:17 PetBody:18 description: A JSON object containing pet information19 required: true20 content:21 application/json:22 schema:23 $ref: '#/components/schemas/Pet'表单数据
术语“表单数据”用于媒体类型 application/x-www-form-urlencoded 和 multipart/form-data,它们通常用于提交 HTML 表单。
application/x-www-form-urlencoded用于以key=value对的形式发送简单的 ASCII 文本数据。其有效负载格式类似于查询参数。multipart/form-data允许在单个消息中提交二进制数据以及多种媒体类型(例如,图像和 JSON)。每个表单字段在有效负载中都有自己的部分,并带有内部 HTTP 头。multipart请求通常用于文件上传。
为了说明表单数据,考虑一个 HTML POST 表单
1<form action="http://example.com/survey" method="post">2 <input type="text" name="name" />3 <input type="number" name="fav_number" />4 <input type="submit" />5</form>此表单将数据 POST 到表单的端点
1POST /survey HTTP/1.12Host: example.com3Content-Type: application/x-www-form-urlencoded4Content-Length: 285
6name=Amy+Smith&fav_number=42在 OpenAPI 3.0 中,表单数据使用 type: object 模式建模,其中对象属性表示表单字段
1paths:2 /survey:3 post:4 requestBody:5 required: true6 content:7 application/x-www-form-urlencoded:8 schema:9 type: object10 properties:11 name: # <!--- form field name12 type: string13 fav_number: # <!--- form field name14 type: integer15 required:16 - name17 - email表单字段可以包含基本类型值、数组和对象。默认情况下,数组序列化为 array_name=value1&array_name=value2,对象序列化为 prop1=value1&prop=value2,但您可以使用 OpenAPI 3.0 规范中定义的其他序列化策略。序列化策略在 encoding 部分中指定,如下所示
1requestBody:2 content:3 application/x-www-form-urlencoded:4 schema:5 type: object6 properties:7 color:8 type: array9 items:10 type: string11 encoding:12 color: # color=red,green,blue13 style: form14 explode: false默认情况下,application/x-www-form-urlencoded 正文中的表单字段值中的保留字符 :/?#[]@!$&'()*+,;= 在发送时会被进行百分比编码。为了允许这些字符按原样发送,请使用 allowReserved 关键字,如下所示
1requestBody:2 content:3 application/x-www-form-urlencoded:4 schema:5 type: object6 properties:7 foo:8 type: string9 bar:10 type: string11 baz:12 type: string13 encoding:14 # Don't percent-encode reserved characters in the values of "bar" and "baz" fields15 bar:16 allowReserved: true17 baz:18 allowReserved: true任意 key=value 对可以使用自由格式模式进行建模
1requestBody:2 content:3 application/x-www-form-urlencoded:4 schema:5 type: object6 additionalProperties: true # this line is optional表单数据中的复杂序列化
style 和 explode 关键字提供的序列化规则仅对基本类型数组和具有基本属性的对象定义了行为。对于更复杂的场景,例如嵌套数组或表单数据中的 JSON,您需要使用 contentType 关键字来指定复杂字段值编码的媒体类型。以 Slack 入站 Webhook 为例。消息可以直接作为 JSON 发送,或者 JSON 数据可以像这样在名为 payload 的表单字段内发送(在应用 URL 编码之前)
1payload={"text":"Swagger is awesome"}这可以描述为
1openapi: 3.0.42info:3 version: 1.0.04 title: Slack Incoming Webhook5externalDocs:6 url: https://api.slack.com/incoming-webhooks7
8servers:9 - url: https://hooks.slack.com10
11paths:12 /services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX:13 post:14 summary: Post a message to Slack15 requestBody:16 content:17 application/json:18 schema:19 $ref: "#/components/schemas/Message"20
21 application/x-www-form-urlencoded:22 schema:23 type: object24 properties:25 payload: # <--- form field that contains the JSON message26 $ref: "#/components/schemas/Message"27 encoding:28 payload:29 contentType: application/json30
31 responses:32 "200":33 description: OK34
35components:36 schemas:37 Message:38 title: A Slack message39 type: object40 properties:41 text:42 type: string43 description: Message text44 required:45 - text