FastAPI 之所以成为 Python Web 开发的主流选择,很大程度上得益于它在请求处理和响应构建上的设计哲学:类型安全、自动验证、开箱即用的文档。本文将从请求数据的接收开始,逐步深入到响应构建的方方面面,最终探讨请求与响应机制在实际项目中的典型应用场景。

一、请求:从 HTTP 到 Python 对象
当客户端发送一个 HTTP 请求到 FastAPI 服务时,框架需要完成一个核心任务:将原始 HTTP 数据转换为 Python 对象,以便业务逻辑可以直接使用。

FastAPI 将请求中的数据分为三大类,每一类都有对应的声明方式。

1. 路径参数(Path Parameters)
路径参数嵌入在 URL 路径中,用于标识具体资源。

from fastapi import FastAPI

app = FastAPI()

@app.get("/users/{user_id}")
async def get_user(user_id: int):
    return {"user_id": user_id, "name": f"用户{user_id}"}

FastAPI 会自动将 user_id 从字符串转换为 int 类型。如果传入 "abc",框架会返回清晰的验证错误。

2. 查询参数(Query Parameters)
查询参数位于 URL 的 ? 之后,常用于过滤、排序和分页。

@app.get("/items/")
async def list_items(skip: int = 0, limit: int = 10, category: str | None = None):
    return {"skip": skip, "limit": limit, "category": category}

未在路径中声明的参数会被自动识别为查询参数,并支持默认值和可选类型。

3. 请求体(Request Body)
请求体位于 HTTP 消息体中,用于创建或更新资源时传递结构化数据。FastAPI 使用 Pydantic 模型来定义和验证请求体。

from pydantic import BaseModel

class CreateUserRequest(BaseModel):
    username: str
    email: str
    age: int = 0

@app.post("/users/")
async def create_user(user: CreateUserRequest):
    return {"username": user.username, "email": user.email}

Pydantic 会自动完成类型校验——如果 age 传入字符串,FastAPI 会返回 422 Unprocessable Entity 状态码和详细的错误信息。对于嵌套字段、自定义校验器等复杂场景,Pydantic 同样提供了完善的支持。

4. 请求头与 Cookies

请求头(Headers)和 Cookies 同样可以通过类型声明轻松获取:

from fastapi import Header, Cookie

@app.get("/with-headers/")
async def read_with_headers(
    user_agent: str = Header(None),
    session_id: str = Cookie(None)
):
    return {"user_agent": user_agent, "session_id": session_id}

5. 直接使用 Request 对象
在某些场景下,你可能需要访问原始请求对象——例如获取客户端的 IP 地址。

from fastapi import FastAPI, Request

app = FastAPI()

@app.get("/client-info/")
async def get_client_info(request: Request):
    return {
        "client_host": request.client.host,
        "url": str(request.url),
        "method": request.method
    }

只需将参数类型声明为 Request,FastAPI 就会自动注入。

注意:直接从 Request 对象提取数据(如读取请求体)时,这些数据不会被 FastAPI 自动验证、转换或生成文档。因此,应优先使用 Pydantic 模型等方式声明请求数据,仅在确实需要原始对象时才使用 Request。

6. 文件上传
FastAPI 使用 File 和 UploadFile 处理文件上传:

from fastapi import FastAPI, File, UploadFile

app = FastAPI()

@app.post("/upload/")
async def upload_file(file: UploadFile = File(...)):
    contents = await file.read()
    return {
        "filename": file.filename,
        "content_type": file.content_type,
        "size": len(contents)
    }

UploadFile 提供了异步的 read()、write() 等方法,适合处理大文件场景。

二、响应:将结果返回给客户端
接收请求只是第一步,如何将处理结果以正确的格式返回给客户端同样关键。

1. 默认 JSON 响应
FastAPI 默认返回 JSON 响应。你只需返回 Python 字典、列表或 Pydantic 模型,框架会自动完成序列化:

@app.get("/default/")
async def default_response():
    return {"message": "Hello World", "status": "success"}

FastAPI 内部会使用 jsonable_encoder 将数据转换为 JSON 兼容格式,然后封装为 JSONResponse。

2. 响应模型(Response Model)
通过 response_model 参数,你可以精确控制返回数据的结构和类型:

from pydantic import BaseModel

class UserResponse(BaseModel):
    id: int
    username: str
    email: str

@app.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int):
    # 假设从数据库获取
    return {"id": user_id, "username": "张三", "email": "zhangsan@example.com", "internal_field": "隐藏"}

response_model 会:

过滤:不在模型中的字段(如 internal_field)会被自动过滤掉

转换:自动完成类型转换

文档化:在 OpenAPI 文档中生成精确的响应结构

性能提示:使用 response_model 比直接返回 JSONResponse 性能更好,因为数据序列化由 Pydantic 在 Rust 层面完成。

3. 状态码
通过 status_code 参数可以指定 HTTP 状态码:

@app.post("/users/", status_code=201)
async def create_user(user: CreateUserRequest):
    return {"id": 1, "username": user.username}

4. 响应头与 Cookies
在路径操作函数中声明 Response 类型的参数,即可设置响应头和 Cookies:

from fastapi import FastAPI, Response

app = FastAPI()

@app.post("/login/")
async def login(response: Response):
    response.set_cookie(key="session_id", value="abc123", httponly=True)
    response.headers["X-Request-ID"] = "req-001"
    return {"message": "登录成功"}

FastAPI 会从临时 Response 对象中提取 Cookies 和 Headers,合并到最终响应中。

也可以直接返回一个完整的 Response 对象:

from fastapi.responses import JSONResponse

@app.get("/direct/")
async def direct_response():
    content = {"message": "Hello"}
    headers = {"X-Custom": "value"}
    response = JSONResponse(content=content, headers=headers)
    response.set_cookie(key="token", value="xyz")
    return response

三、自定义响应类型
除了默认的 JSON,FastAPI 支持多种响应类型,通过 response_class 参数指定:

1. HTMLResponse
返回 HTML 页面:

from fastapi.responses import HTMLResponse

@app.get("/page/", response_class=HTMLResponse)
async def get_html():
    return """
    <html>
        <head><title>FastAPI</title></head>
        <body><h1>Hello World!</h1></body>
    </html>
    """

2. PlainTextResponse
返回纯文本:

from fastapi.responses import PlainTextResponse

@app.get("/text/", response_class=PlainTextResponse)
async def get_text():
    return "Hello, this is plain text."

3. RedirectResponse
重定向到其他 URL:

from fastapi.responses import RedirectResponse

@app.get("/go/")
async def redirect():
    return RedirectResponse("https://fastapi.tiangolo.com")

4. FileResponse
返回文件供客户端下载:

from fastapi.responses import FileResponse

@app.get("/download/")
async def download_file():
    return FileResponse(
        "./files/report.pdf",
        filename="report.pdf",
        media_type="application/pdf"
    )

5. StreamingResponse
流式传输大文件或实时数据,无需一次性加载到内存:

from fastapi.responses import StreamingResponse
import asyncio

async def data_generator():
    for i in range(100):
        yield f"data: {i}\n\n"
        await asyncio.sleep(0.1)

@app.get("/stream/")
async def stream_data():
    return StreamingResponse(data_generator(), media_type="text/event-stream")

这在 AI 对话流式输出、实时日志推送等场景中尤为实用。

6. 直接返回 Response 对象
你也可以直接返回任何 Response 子类的实例:

from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder
from datetime import datetime

class Item(BaseModel):
    title: str
    timestamp: datetime

@app.put("/items/{id}")
async def update_item(id: str, item: Item):
    # 需要手动将 Pydantic 模型转换为 JSON 兼容格式
    json_compatible = jsonable_encoder(item)
    return JSONResponse(content=json_compatible)

直接返回 Response 时,FastAPI 不会自动进行数据转换或验证——这给了你最大的灵活性,也意味着你需要自己确保数据的正确性。

四、FastAPI 请求与响应的典型应用场景
1. RESTful API 服务
这是 FastAPI 最核心的应用场景。通过路径参数定位资源、查询参数进行过滤分页、请求体承载创建/更新数据、响应模型规范输出结构,FastAPI 提供了一套完整的 RESTful API 开发范式。

典型案例:

电商平台的商品管理 API(CRUD 操作)

用户管理与认证系统(注册、登录、个人信息)

内容管理系统的文章发布与查询接口

2. AI 模型服务与推理接口
FastAPI 的异步能力和自动文档生成,使其成为机器学习模型部署的首选框架。

典型案例:

图像分类/目标检测服务:接收图片文件(UploadFile),返回识别结果 JSON

文本生成/翻译服务:接收文本请求体,流式返回生成结果(StreamingResponse)

推荐系统服务:接收用户 ID 和上下文参数,返回个性化推荐列表

3. 大模型与 AI Agent 应用
在构建 LLM 应用和 AI Agent 时,请求与响应机制尤为重要:

RAG 系统:接收用户问题(请求体),检索知识库后返回答案(JSON 响应)

Agent 对话:支持流式输出(StreamingResponse)实现打字机效果

多模态输入:同时接收文本和文件(Form + File),返回综合分析结果

4. 文件处理服务
利用 UploadFile 和 FileResponse,FastAPI 可以轻松构建文件处理服务:

典型案例:

图片上传与缩略图生成服务

文档格式转换服务(如 Markdown → PDF)

CSV/Excel 数据导入导出服务

大文件分片上传与断点续传

5. 实时数据推送
StreamingResponse 让 FastAPI 能够处理实时数据流:

典型案例:

服务器发送事件(SSE)推送实时通知

日志流式查看与监控

实时数据仪表板后端

AI 对话的流式输出

6. 微服务网关与中间层
在微服务架构中,FastAPI 常作为 API 网关或聚合层:

典型案例:

请求路由与负载均衡(通过 RedirectResponse)

多后端服务的数据聚合(一个请求调用多个下游服务,合并返回)

认证鉴权中间层(解析 Token、注入用户信息到请求上下文)

五、最佳实践
1. 始终使用 Pydantic 模型定义请求体
Pydantic 提供了类型安全、自动验证和清晰的 API 文档。避免直接操作原始 Request 对象,除非确实需要访问框架未提供的底层信息。

2. 使用 response_model 规范输出
response_model 不仅能过滤敏感字段,还能生成精确的 OpenAPI 文档,对前端开发者极其友好。

3. 合理使用异步
FastAPI 原生支持 async/await。对于 I/O 密集型操作(数据库查询、外部 API 调用、文件读写),使用异步可以显著提升吞吐量。

@app.post("/process/")
async def process_data(data: InputModel):
    # 异步数据库查询
    result = await db.query(data)
    # 异步外部 API 调用
    response = await httpx.AsyncClient().get("https://api.example.com")
    return result

4. 善用依赖注入(Depends)
依赖注入可以将请求处理中的公共逻辑(如认证、数据库会话、配置读取)抽取为可复用组件:

from fastapi import Depends

async def get_current_user(token: str = Header(...)):
    # 验证 token,返回用户信息
    return user

@app.get("/protected/")
async def protected_route(current_user = Depends(get_current_user)):
    return {"user": current_user}

5. 统一异常处理
通过自定义异常处理器,可以统一 API 的错误响应格式:

from fastapi import HTTPException
from fastapi.exceptions import RequestValidationError

@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
    return JSONResponse(
        status_code=422,
        content={"code": 40001, "message": "参数验证失败", "details": exc.errors()}
    )

六、结语
FastAPI 的请求与响应机制,本质上解决了一个 Web 框架最核心的问题:如何让开发者用最少的代码、最高的安全性,完成从 HTTP 请求到业务逻辑再到 HTTP 响应的全链路转换。

通过 Pydantic 模型声明请求体、通过类型注解声明路径参数和查询参数、通过 response_model 规范输出、通过多种 Response 子类应对不同场景——FastAPI 将请求与响应的处理变成了一套声明式、类型安全、自动文档化的优雅体系。

无论你是在构建一个简单的 REST API、部署一个机器学习模型,还是开发一个复杂的 AI Agent 系统,理解并善用 FastAPI 的请求与响应机制,都将是你构建高质量 Web 服务的第一步。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐