『FastAPI』快速掌握“请求与响应”的基础用法
点赞 + 关注 + 收藏 = 学会了
本文简介
上一讲介绍了 FastAPI
的基础用法,这一讲我们聊聊 FastAPI
常用的请求方法、获取前端传过来的数据以及返回数据给前端。
常见的请求方法
现在流行 RESTful
的 API
设计规范,RESTful
是基于 REST(Representational State Transfer)架构风格的 Web 服务设计原则。REST 将一切事物视为资源,每个资源由 URI(Uniform Resource Identifier,统一资源标识符)进行唯一标识。
RESTful API
通过标准的 HTTP
方法与资源进行交互,通常包括以下常见方法:
GET
:从服务器读取资源(查询资源)。POST
:在服务器创建资源(通常用于添加新资源)。PUT
:在服务器更新资源(通常用于替换或更新现有资源)。DELETE
:从服务器删除资源。PATCH
:部分更新资源。
FastAPI
当然也支持这几种请求方法啦,而且写起来非常简单。
简单来说,一行「装饰器」写明路由、请求参数,下面跟着一个「方法」来处理这个路由的请求。
from fastapi import FastAPI # 引入FastAPI
app = FastAPI() # 注册 app
@app.请求方法("路径")
def xxx():
先用不带参数的方法演示一下。
from fastapi import FastAPI # 引入FastAPI
app = FastAPI() # 注册 app
# get方法
@app.get("/demo")
def demoGet():
return {"msg": "这是GET"}
# post方法
@app.post("/demo")
def demoPost():
return {"msg": "这是POST"}
# put方法
@app.put("/demo")
def demoPut():
return {"msg": "这是PUT"}
# patch方法
@app.patch("/demo")
def demoPatch():
return {"msg": "这是PATCH"}
# delete方法
@app.delete("/demo")
def demoDelete():
return {"msg": "这是DELETE"}
if __name__ == "__main__":
import uvicorn
uvicorn.run('main:app', host="127.0.0.1", port=8000, reload=True, workers=1)
上面的代码很简单,我通过 @app.xxx
写了5个接口,这些接口对应的路由地址都是 /demo
,只不过他们的请求方法不一样。
最后一段代码 uvicorn.run('main:app', host="127.0.0.1", port=8000, reload=True, workers=1)
的作用是通过 uvicorn
启动一个本地服务,地址是 127.0.0.1
,端口是 8000
,而且你的代码发生变化后它也会自动给你重启服务器。
此时使用 Postman
(你用其他工具也行)请求一下 http://127.0.0.1:8000/demo
可以看到对应的返回内容。
比如用 PATCH
方法请求:
是不是很简单~
日常工作中,尤其是中小公司其实没那么遵守 RESTful
规范,大多数时候都是用 GET
和 POST
。接下来我主要用这两个方法讲解接下来的内容,其他方法的用法其实也是一样的。
获取请求参数
客户端像服务器发起请求,通常会带一些参数。
如果是 GET
请求,通常会在 URL 上带「路径参数」和「查询参数」。
POST
请求除了「路径参数」和「查询参数」外,还有「请求头」信息也能获取到,还可以通过「请求体」把数据传给后端。
路径参数
「路径参数」是在 URL 中定义的一部分,通常用于标识某个特定的资源,例如我的掘金个人页面的地址是 https://juejin.cn/user/2673620576140030
。每个人都可以通过 https://juejin.cn/user
访问用户首页,但要在这个 URL
后面拼一个用户 id
。 2673620576140030
就是我掘金账号的 id
。
如果我们要实现这种请求,可以这么做。
@app.get("/demo/{userId}")
def demoGet(userId: int):
return {
"msg": "这是GET",
"userId": f"这是用户ID:{userId}"
}
在路由部分定义了一个 int
型的路径参数 userid
,当你访问 /demo/123
时,userid
的值为 123。并且会作为函数参数传递到 demoGet
函数中。
还可以定义多个路径参数
@app.get("/demo/{userId}/{orderId}")
def demoGet(userId: int, orderId: int):
return {
"msg": "这是GET",
"userId": f"这是用户ID:{userId}",
"orderId": orderId
}
查询参数
「查询参数」是 URL 中 ?
之后的一部分,通常用在过滤、分页、排序等查询操作(当然,这些操作你也可以照样写在路径参数或者请求体里)。
「查询参数」与「路径参数」不同,「路径参数」是 URL 的一部分,而「查询参数」则在 URL 路径后添加,用于指定可选的附加数据。
查询参数的特点
- 非必需:查询参数通常用于提供可选信息,因此在许多情况下它们是可选的。
- 灵活性:可以使用多个查询参数进行数据过滤、分页、排序等操作。
- 键值对:查询参数的形式是
key=value
,如:?search=keyword&limit=10
。 - 顺序不重要:多个查询参数之间的顺序不影响请求结果。
举个例子,创建一个查询博客列表的接口。
@app.get("/blogList")
def getBlogList(limit: int = 10, page: int = 1, search: str = None):
return {
"limit": limit,
"page": page,
"search": search
}
在这个例子中,limit
和 page
参数具有默认值,而 search
参数是可选的,没有指定默认值,因此默认为 None
。
此时访问 http://127.0.0.1:8000/blogList?limit=20&page=1&search=FastAPI
就会进入 getBlogList
,会将这些参数返回给客户端。
需要注意的是,「查询参数」的参数不需要在装饰器里定义,直接写在函数参数里即可。
请求头参数
「请求头」是 HTTP 请求中的元数据,用于传递有关请求的附加信息。
比如客户端的类型、身份验证信息、内容类型等。它们位于 HTTP 请求的顶部,通常包含键值对形式的数据。
常见的请求头字段包括:
Authorization
: 用于身份验证,例如 Bearer Token。Content-Type
: 指示请求体的数据类型,如application/json
。User-Agent
: 标识客户端应用或浏览器的信息。Accept
: 指定客户端可接受的数据格式,如application/json
。
举个例子
from fastapi import FastAPI, Header
from typing import Optional
app = FastAPI()
@app.get("/headers/")
def getHeaders(user_agent: Optional[str] = Header(None), content_type: Optional[str] = Header(None)):
return {
"User-Agent": user_agent,
"Content-Type": content_type
}
在这个例子中
-
Header(None)
:告诉FastAPI
,这个请求头是可选的。如果客户端没有传递该请求头,值会是None
。 -
user_agent: Optional[str]
:获取请求中的User-Agent
头,它表示客户端(例如浏览器或移动设备)的详细信息。 -
content_type: Optional[str]
:获取请求中的Content-Type
头,它表示请求体的媒体类型(如application/json
)。
获取请求头的所有信息
如果你需要获取请求的所有请求头,可以通过 request.headers
来获取。
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/headers")
def getHeaders(request: Request):
headers = request.headers
return dict(headers)
此时在浏览器访问 http://127.0.0.1:8000/headers
就会展示以下信息。
请求体数据
POST
请求通常用于向服务器发送数据(例如表单数据或 JSON 数据),这些数据会被放置在请求体中。
FastAPI
通过 Pydantic
模型或请求体字段来提取和验证这些数据。我们可以指定请求体中的参数,并控制它们是否为必填项。
先看看怎么写。
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str
price: float
tax: float = 0.0 # 设置默认值为 0.0
@app.post("/items/")
async def createItem(item: Item):
return {
"name": item.name,
"description": item.description,
"price": item.price,
"tax": item.tax
}
使用 Pydantic
模型来定义请求体的数据结构。Pydantic
会自动验证传入的数据,并确保其符合指定的类型和规则。通过这种方式,可以确保参数的必填性和数据格式。
上面这个例子定义了一个 Item
类,这个类定义了一个包含四个字段的请求体:
name
: 必填,字符串类型。description
: 必填,字符串类型。price
: 必填,浮点数类型。tax
: 可选,浮点数类型,默认值为0.0
。
此时通过 Postman 向 http://127.0.0.1:8000/items
发起一个 POST
请求,在 Body
里传入以下数据。
{
"name": "雷猴之书",
"description": "这是一本教你如何打招呼的书",
"price": 29.99
}
以上就是本文的全部内容,相信你已经能用 FastAPI
写出各种请求方法的接口了。
但如果把所有接口都写在同一个文件中,接口多了就不好维护了。
下一讲介绍「路由分发」解决这个问题。
点赞 + 关注 + 收藏 = 学会了