文章目录
- [FastAPI 重要知识点补充:reponse 与 request 的区别](#FastAPI 重要知识点补充:reponse 与 request 的区别)
-
- [一、Web 通信的最简模型](#一、Web 通信的最简模型)
- [二、什么是 Request(请求)?](#二、什么是 Request(请求)?)
-
- [1. 自动解析请求数据(最常用)](#1. 自动解析请求数据(最常用))
- [2. 直接使用 Request 对象(需要底层信息时)](#2. 直接使用 Request 对象(需要底层信息时))
- [三、什么是 Response(响应)?](#三、什么是 Response(响应)?)
-
- [1. 自动转换响应](#1. 自动转换响应)
- [2. 手动控制响应细节](#2. 手动控制响应细节)
- [四、一张表看懂 Request 和 Response 的区别](#四、一张表看懂 Request 和 Response 的区别)
- 五、进阶用法:请求与响应的中间件拦截
- 六、常见易错点提醒
-
- [1. 请求体只能读取一次](#1. 请求体只能读取一次)
- [2. 返回字典 ≠ 没有响应对象](#2. 返回字典 ≠ 没有响应对象)
- [3. `response` 参数仅用于修改元数据](#3.
response参数仅用于修改元数据)
- 七、总结
FastAPI 重要知识点补充:reponse 与 request 的区别
刚开始学习 FastAPI 时,很多同学会频繁听到两个词:Request 和 Response。它们就像快递包裹中的"寄件单"和"回执单",一个代表客户端发给服务器的请求,另一个代表服务器返回给客户端的结果。理解清楚这对概念,是写好 Web 接口的第一步。
今天这篇博客就专门来聊聊:在 FastAPI 中,Request 和 Response 到底有什么区别?分别怎么用?
一、Web 通信的最简模型
你可以把 Web 交互想象成一次"点外卖":
- 你(客户端 )拿起手机,选好菜品,填写地址,点击"下单" → 这就是一次 请求(Request)。
- 餐厅(服务器 )收到订单,做好饭菜,交给骑手送给你 → 这就是一次 响应(Response)。
在 FastAPI 里,我们写的每一个接口函数,本质上就是在处理请求 ,并返回一个响应。
二、什么是 Request(请求)?
Request 是客户端发往服务器的数据包。 它告诉服务器:"我是谁,我想干什么,我带了哪些数据。"
在 FastAPI 中,你既可以通过参数声明自动提取请求信息,也可以直接获取底层的 Request 对象。
1. 自动解析请求数据(最常用)
FastAPI 会根据你函数参数的声明,自动从请求的不同位置提取数据:
python
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.post("/items/{item_id}")
async def create_item(
item_id: int, # 路径参数
q: str | None = None, # 查询参数
item: Item = None, # 请求体(JSON)
):
return {
"item_id": item_id,
"query": q,
"item_name": item.name
}
- 路径参数 :URL 中的一部分,如
/items/123里的123。 - 查询参数 :URL
?后面的键值对,如?q=apple。 - 请求体:POST、PUT 等请求中携带的 JSON 数据。
2. 直接使用 Request 对象(需要底层信息时)
有时候我们需要获取客户端 IP、请求头、Cookie 等原始信息,这时可以直接注入 Request 对象:
python
from fastapi import FastAPI, Request
app = FastAPI()
@app.get("/info")
async def get_info(request: Request):
client_host = request.client.host
user_agent = request.headers.get("user-agent")
return {
"client_ip": client_host,
"browser": user_agent
}
Request 对象包含了请求的所有原始细节,比如:
request.method:请求方法(GET、POST 等)request.url:完整 URLrequest.headers:请求头字典request.cookies:Cookie 信息request.body():原始请求体(异步方法)
三、什么是 Response(响应)?
Response 是服务器返回给客户端的数据包。 它包含了你真正关心的内容(比如 JSON 数据、HTML 页面、文件),以及状态码、响应头等元信息。
在 FastAPI 中,最简单的返回方式就是 return 一个字典、列表或 Pydantic 模型,FastAPI 会自动帮你转换成 JSON 响应,状态码默认为 200。
1. 自动转换响应
python
@app.get("/hello")
async def hello():
return {"message": "Hello World"}
当你访问这个接口时,客户端会收到:
- 状态码:
200 OK - 响应体:
{"message": "Hello World"} - 响应头:
content-type: application/json
2. 手动控制响应细节
如果需要自定义状态码、响应头、Cookie 等,可以使用 Response 对象或其子类(如 JSONResponse、HTMLResponse)。
直接返回 Response 对象:
python
from fastapi import FastAPI, Response
app = FastAPI()
@app.get("/custom")
async def custom_response():
content = "This is plain text"
return Response(
content=content,
media_type="text/plain",
headers={"X-Custom-Header": "my-value"},
status_code=201
)
更常见的:设置状态码和 Cookie(通过 response 参数)
FastAPI 允许在函数参数中声明一个 response 参数(类型为 Response),通过它来修改响应属性,但实际返回的仍然是你 return 的数据。
python
from fastapi import FastAPI, Response
@app.post("/login")
async def login(response: Response):
# 设置一个 Cookie
response.set_cookie(key="session_id", value="abc123")
# 返回的 JSON 内容会自动处理,但 Cookie 会被带上
return {"msg": "Login success"}
四、一张表看懂 Request 和 Response 的区别
| 对比维度 | Request(请求) | Response(响应) |
|---|---|---|
| 方向 | 客户端 → 服务器 | 服务器 → 客户端 |
| 发起者 | 客户端(浏览器、Postman、代码) | 服务器 |
| 包含内容 | 请求方法、URL、请求头、请求体 | 状态码、响应头、响应体 |
| 在 FastAPI 中的角色 | 输入数据,用来接收客户端信息 | 输出数据,用来返回结果给客户端 |
| 常用操作 | 获取路径参数、查询参数、表单、JSON 请求体、IP 地址 | 设置状态码、响应头、Cookie、返回不同类型数据 |
| 获取方式 | 参数声明 / 注入 Request 对象 |
返回字典 / 模型 / Response 对象 |
五、进阶用法:请求与响应的中间件拦截
FastAPI 的中间件可以在请求到达接口之前 和响应发出之前对它们进行统一处理,非常适合做日志记录、跨域处理、性能监控。
python
from fastapi import FastAPI, Request
import time
app = FastAPI()
@app.middleware("http")
async def log_requests(request: Request, call_next):
# 请求处理前
start_time = time.time()
print(f"收到请求:{request.method} {request.url}")
# 调用真正的接口函数,得到响应
response = await call_next(request)
# 响应发出前
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
print(f"请求处理完成,耗时 {process_time:.4f} 秒")
return response
这里 request 就是请求对象,response 是即将返回的响应对象,我们可以任意修改它。
六、常见易错点提醒
1. 请求体只能读取一次
Request 对象的 .body() 方法是异步的,并且流只能读取一次 。如果你在中间件里读了请求体,后面的接口函数就无法再读到 JSON 数据了。此时需要特殊处理(比如将读取结果存储到 request.state 中)。
2. 返回字典 ≠ 没有响应对象
即使你只写了 return {"msg": "ok"},FastAPI 也会在背后帮你创建一个 JSONResponse 对象,并设置好对应的状态码和响应头。
3. response 参数仅用于修改元数据
在函数参数中使用 response: Response 时,千万不要在函数里 return response ,否则你手动返回的响应会覆盖 FastAPI 的自动转换,导致错误。它的正确用法是:只用来调用 response.set_cookie()、response.headers["xxx"] = "yyy",然后仍然 return 你真正的内容数据。
七、总结
- Request 是客户端给你的"输入",你需要从中提取有用信息。
- Response 是你给客户端的"输出",你要决定返回什么内容、状态是什么。
- FastAPI 提供了自动解析 和手动控制两种方式,让你在简单场景和复杂需求间灵活切换。
理解了 Request 和 Response 的区别,就能更清晰地掌握整个 Web 请求的生命周期。接下来再去学习 FastAPI 的依赖注入、异常处理、后台任务等高级特性时,会发现它们都建立在请求-响应的基础之上。