# 声明请求示例数据 { #declare-request-example-data } 你可以为你的应用将接收的数据声明示例。 这里有几种实现方式。 ## Pydantic 模型中的额外 JSON Schema 数据 { #extra-json-schema-data-in-pydantic-models } 你可以为一个 Pydantic 模型声明 `examples`,它们会被添加到生成的 JSON Schema 中。 {* ../../docs_src/schema_extra_example/tutorial001_py310.py hl[13:24] *} 这些额外信息会原样添加到该模型输出的 JSON Schema 中,并会在 API 文档中使用。 你可以使用属性 `model_config`,它接收一个 `dict`,详见 Pydantic 文档:配置。 你可以设置 `"json_schema_extra"`,其值为一个 `dict`,包含你希望出现在生成 JSON Schema 中的任意附加数据,包括 `examples`。 /// tip | 提示 你也可以用同样的技巧扩展 JSON Schema,添加你自己的自定义额外信息。 例如,你可以用它为前端用户界面添加元数据等。 /// /// info | 信息 OpenAPI 3.1.0(自 FastAPI 0.99.0 起使用)增加了对 `examples` 的支持,它是 JSON Schema 标准的一部分。 在此之前,只支持使用单个示例的关键字 `example`。OpenAPI 3.1.0 仍然支持它,但它已被弃用,并不属于 JSON Schema 标准。因此,建议你把 `example` 迁移到 `examples`。🤓 你可以在本页末尾阅读更多内容。 /// ## `Field` 的附加参数 { #field-additional-arguments } 在 Pydantic 模型中使用 `Field()` 时,你也可以声明额外的 `examples`: {* ../../docs_src/schema_extra_example/tutorial002_py310.py hl[2,8:11] *} ## JSON Schema 中的 `examples` - OpenAPI { #examples-in-json-schema-openapi } 在以下任意场景中使用: - `Path()` - `Query()` - `Header()` - `Cookie()` - `Body()` - `Form()` - `File()` 你也可以声明一组 `examples`,这些带有附加信息的示例将被添加到它们在 OpenAPI 中的 JSON Schema 里。 ### 带有 `examples` 的 `Body` { #body-with-examples } 这里我们向 `Body()` 传入 `examples`,其中包含一个期望的数据示例: {* ../../docs_src/schema_extra_example/tutorial003_an_py310.py hl[22:29] *} ### 文档 UI 中的示例 { #example-in-the-docs-ui } 使用上述任一方法,在 `/docs` 中看起来会是这样: ### 带有多个 `examples` 的 `Body` { #body-with-multiple-examples } 当然,你也可以传入多个 `examples`: {* ../../docs_src/schema_extra_example/tutorial004_an_py310.py hl[23:38] *} 这样做时,这些示例会成为该请求体数据内部 JSON Schema 的一部分。 不过,在撰写本文时,用于展示文档 UI 的 Swagger UI 并不支持显示 JSON Schema 中数据的多个示例。但请继续阅读,下面有一种变通方法。 ### OpenAPI 特定的 `examples` { #openapi-specific-examples } 在 JSON Schema 支持 `examples` 之前,OpenAPI 就已支持一个同名但不同的字段 `examples`。 这个面向 OpenAPI 的 `examples` 位于 OpenAPI 规范的另一处。它放在每个路径操作的详细信息中,而不是每个 JSON Schema 里。 而 Swagger UI 早就支持这个特定的 `examples` 字段。因此,你可以用它在文档 UI 中展示不同的示例。 这个 OpenAPI 特定字段 `examples` 的结构是一个包含多个示例的 `dict`(而不是一个 `list`),每个示例都包含会被添加到 OpenAPI 的额外信息。 这不放在 OpenAPI 内部包含的各个 JSON Schema 里,而是直接放在路径操作上。 ### 使用 `openapi_examples` 参数 { #using-the-openapi-examples-parameter } 你可以在 FastAPI 中通过参数 `openapi_examples` 来声明这个 OpenAPI 特定的 `examples`,适用于: - `Path()` - `Query()` - `Header()` - `Cookie()` - `Body()` - `Form()` - `File()` 这个 `dict` 的键用于标识每个示例,每个值是另一个 `dict`。 `examples` 中每个具体示例的 `dict` 可以包含: - `summary`:该示例的简短描述。 - `description`:较长描述,可以包含 Markdown 文本。 - `value`:实际展示的示例,例如一个 `dict`。 - `externalValue`:`value` 的替代项,指向该示例的 URL。不过它的工具支持度可能不如 `value`。 你可以这样使用: {* ../../docs_src/schema_extra_example/tutorial005_an_py310.py hl[23:49] *} ### 文档 UI 中的 OpenAPI 示例 { #openapi-examples-in-the-docs-ui } 当把 `openapi_examples` 添加到 `Body()` 后,`/docs` 会如下所示: ## 技术细节 { #technical-details } /// tip | 提示 如果你已经在使用 FastAPI 版本 0.99.0 或更高版本,你大概率可以跳过这些细节。 它们对更早版本(OpenAPI 3.1.0 尚不可用之前)更相关。 你可以把这当作一堂简短的 OpenAPI 和 JSON Schema 历史课。🤓 /// /// warning | 警告 以下是关于 JSON Schema 和 OpenAPI 标准的非常技术性的细节。 如果上面的思路对你已经足够可用,你可能不需要这些细节,可以直接跳过。 /// 在 OpenAPI 3.1.0 之前,OpenAPI 使用的是一个更旧且经过修改的 JSON Schema 版本。 当时 JSON Schema 没有 `examples`,所以 OpenAPI 在它修改过的版本中添加了自己的 `example` 字段。 OpenAPI 还在规范的其他部分添加了 `example` 和 `examples` 字段: - `Parameter Object`(规范中),被 FastAPI 的以下内容使用: - `Path()` - `Query()` - `Header()` - `Cookie()` - `Request Body Object` 中的 `content` 字段里的 `Media Type Object`(规范中),被 FastAPI 的以下内容使用: - `Body()` - `File()` - `Form()` /// info | 信息 这个旧的、OpenAPI 特定的 `examples` 参数,自 FastAPI `0.103.0` 起改名为 `openapi_examples`。 /// ### JSON Schema 的 `examples` 字段 { #json-schemas-examples-field } 后来,JSON Schema 在新版本的规范中添加了 `examples` 字段。 随后新的 OpenAPI 3.1.0 基于最新版本(JSON Schema 2020-12),其中包含了这个新的 `examples` 字段。 现在,这个新的 `examples` 字段优先于旧的单个(且自定义的)`example` 字段,后者已被弃用。 JSON Schema 中这个新的 `examples` 字段只是一个由示例组成的 `list`,而不是像上面提到的 OpenAPI 其他位置那样带有额外元数据的 `dict`。 /// info | 信息 即使在 OpenAPI 3.1.0 发布、并与 JSON Schema 有了这种更简单的集成之后,有一段时间里,提供自动文档的 Swagger UI 并不支持 OpenAPI 3.1.0(它自 5.0.0 版本起已支持 🎉)。 因此,FastAPI 0.99.0 之前的版本仍然使用低于 3.1.0 的 OpenAPI 版本。 /// ### Pydantic 与 FastAPI 的 `examples` { #pydantic-and-fastapi-examples } 当你在 Pydantic 模型中添加 `examples`,通过 `schema_extra` 或 `Field(examples=["something"])`,这些示例会被添加到该 Pydantic 模型的 JSON Schema 中。 这个 Pydantic 模型的 JSON Schema 会被包含到你的 API 的 OpenAPI 中,然后在文档 UI 中使用。 在 FastAPI 0.99.0 之前的版本(0.99.0 及以上使用更新的 OpenAPI 3.1.0),当你在其他工具(`Query()`、`Body()` 等)中使用 `example` 或 `examples` 时,这些示例不会被添加到描述该数据的 JSON Schema 中(甚至不会添加到 OpenAPI 自己的 JSON Schema 版本中),而是会直接添加到 OpenAPI 的路径操作声明中(在 OpenAPI 使用 JSON Schema 的部分之外)。 但现在 FastAPI 0.99.0 及以上使用 OpenAPI 3.1.0(其使用 JSON Schema 2020-12)以及 Swagger UI 5.0.0 及以上后,一切更加一致,示例会包含在 JSON Schema 中。 ### Swagger UI 与 OpenAPI 特定的 `examples` { #swagger-ui-and-openapi-specific-examples } 此前,由于 Swagger UI 不支持多个 JSON Schema 示例(截至 2023-08-26),用户无法在文档中展示多个示例。 为了解决这个问题,FastAPI `0.103.0` 通过新增参数 `openapi_examples`,为声明同样的旧式 OpenAPI 特定 `examples` 字段提供了支持。🤓 ### 总结 { #summary } 我曾经说我不太喜欢历史……结果现在在这儿上“技术史”课。😅 简而言之,升级到 FastAPI 0.99.0 或更高版本,一切会更简单、一致、直观,你也不必了解这些历史细节。😎