fastapi教程翻译(七):Body - 多种参数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了fastapi教程翻译(七):Body - 多种参数相关的知识,希望对你有一定的参考价值。

参考技术A

现在我们已经了解了如何使用路径 Path 和查询 Query ,让我们来看一下请求主体 Body 声明的更高级用法。

首先,当然,您可以自由地混合使用 Path , Query 和请求主体参数声明, FastAPI 将知道该怎么做。

可以通过将默认值设置为 None 来声明主体参数为可选:

上述请求体参数的正确格式如下:

通过Postman测试如下:

注意: 在这种情况下,将从请求体中提取的 item 是可选的。 由于它具有 None 默认值。

例如: item 和 user 均为 Pydantic 模型

在这种情况下,它将使用参数名称作为正文中的 key , Pydantic 的类作为 key 的内容

上述请求体参数的正确格式如下:

注意: 即使 item 已经和以前一样的被定义,它仍然期望被放在请求体中,使用 item 关键字标记.

Query 和 Path 方法定义了额外的数据为查询和路径参数,FastAPI也为请求体定义了 Body 方法。

例如,扩展之前的模型,之前的模型还需要额外增加一个参数:除去 item 和 user 这两个字段之外,还需要 importance 在请求体中

但是你可以使用 Body 参数,让FastAPI将其视为请求体的key:

在这个例子中,FastAPI的预期的请求体如下:

当然,除了请求体参数外,您还可以在需要时声明其他查询参数。

默认,单个参数会被解析为查询参数,你不必用添加 Query 方法,你只需要

就如:

假设您只有 Pydantic 模型 Item 中的单个 body 参数。

默认情况下,FastAPI将直接希望得到 body 参数。

但是,如果您想得到一个带有key的JSON,并且在key对应的包含模型内容,就像声明额外的主体参数时那样,则可以使用嵌入的特殊Body参数:

如下:

在这个例子中,FastAPI预期的请求体数据格式如下:

而不是(参考文章的第一部分,如果不使用 embed 方法,则默认的传递方式如下):

何时/何地在 FastAPI 中使用正文/路径/查询/字段?

【中文标题】何时/何地在 FastAPI 中使用正文/路径/查询/字段?【英文标题】:When/Where to use Body/Path/Query/Field in FastAPI? 【发布时间】:2021-03-04 00:45:40 【问题描述】:

我正在关注 FastAPI 的 the tutorial,到目前为止,我对 何时/何地在 FastAPI 中使用 Body/Path/Query/Field 有疑问? 因为它们似乎都适用同样,本教程对它们的区别使用了模糊的解释,还是我遗漏了什么?

额外问题* 真的有用吗?我在教程的the sample code 中设置/省略了它,但我看不出有什么区别。

【问题讨论】:

这能回答你的问题吗? When do I use path params vs. query params in a RESTful API? 不,但感谢您的帖子,它在某些方面有所帮助。 【参考方案1】:

其实它们是完全不同的。

我们以带有 FastAPI 链接标签的问题的 URL 为例,进行拆分。

https://***.com/questions/tagged/fastapi?sort=Newest&uqlId=26120
***.com -> 域 /questions -> 路径 /tagged -> 路径 /fastapi -> 路径参数。 sort=Newest -> 查询参数。 uqlId=26120 -> 查询参数。

如果你想在 FastAPI 中创建它,它看起来像这样。

from enum import Enum


class SortTypes(str, Enum):
    newest: str = "Newest"
    unanswered: str = "Unanswered"
    active: str = "Active"
    bountied: str = "Bountied"


@app.get("/questions/tagged/tag")
async def get_questions_with_tags(tag: str, sort: SortTypes, uqlId: int):
    return ...

查询参数和路径参数的工作方式几乎相同。

但身体完全不同。

您看不到来自 URL 的请求正文,您的客户端以字节形式发送 HTTP 正文,但它可以包含任何内容,您需要通过 HTTP 标头指定正文包含的内容。

通过这样做,您是在告诉服务器它应该如何处理该主体。例如

假设您正在发送一个 JSON "name": "foo",它将与此标头 "Content-Type": "application/json" 一起发送,您的客户端会处理此问题,因为默认情况下 FastAPI 返回 JSONResponse,还有其他响应类型,如 StreamingResponse、@987654330 @、HTMLResponse 等(您可以从 here 中读取常见的 Content-Type)。

查询参数和路径参数之间的主要区别在于它们可以从 URL 访问并且它们是字符串。但 Body 但通常是携带数据的。

假设您有一个更大的应用程序,并且您使用Query 参数进行客户端和服务器之间的所有通信。这将是一场彻底的灾难。

例如,现在您正在阅读此答案,对吗?但它是怎么来的?您的身份,您的声誉,问题本身的所有详细信息都以正文形式出现。想象一下在 URL 中发送所有这些,完全是灾难。

如需进一步阅读,您可以查看这些答案以查看设计 REST API 的最佳实践。

REST API Best practices: Where to put parameters? REST API Best practices: args in query string vs in request body

【讨论】:

感谢@yagizcan-degirmenci,我更了解查询和路径参数,因此更了解QUERY、PATH、BODY、FIELD。我认为您可以通过以下电话补充您对 Body 的宝贵解释:curl -X PUT "http://127.0.0.1:8000/items4/345?q=holmes" -H "accept: application/json" -H "Content-Type: application/json" -d "\"item\":\"name\":\"string\",\"description\":\"string\",\"price\":0,\"tax\":0,\"user\":\"username\":\"string\",\"full_name\":\"string\",\"importance\":1" @ΟυιλιαμΑρκευα oh ofc,但主体可以是任何类型、图像、base64 编码字符串、JSON 或字节对象等。我将用对主体的更好解释来更新我的答案.谢谢。

以上是关于fastapi教程翻译(七):Body - 多种参数的主要内容,如果未能解决你的问题,请参考以下文章

fastapi教程翻译(十六):Form Data(表格数据)

FastAPI 学习之路请求体有多个参数如何处理?

17.FastAPI 表单数据

26.FastAPI安全性

何时/何地在 FastAPI 中使用正文/路径/查询/字段?

FastAPI - 支持多种认证依赖