FastAPI 是一个使用 Python 类型注解定义 Web API 的 ASGI Web 框架。它将路由、数据校验、依赖注入和 OpenAPI 描述结合起来,适合构建需要明确数据契约的 HTTP 服务。
FastAPI 应用本身负责描述和处理 API;实际监听网络端口通常还需要 Uvicorn 等 ASGI 服务器。
路径操作
FastAPI 使用装饰器把 HTTP 方法和 URL 路径映射到 Python 函数:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: str):
return {"itemId": item_id}
@app.get()、@app.post()、@app.put() 和 @app.delete() 等装饰器定义路径操作。函数参数中的名称如果出现在路径模板中,会被识别为路径参数;普通标量参数通常会成为查询参数;Pydantic 模型参数通常会成为请求体。
路径操作既可以使用 async def,也可以使用普通 def。按照并发与 async/await 指南,调用需要 await 的异步网络、数据库或文件接口时使用 async def;同步阻塞代码不能仅因为放进异步函数就自动变成非阻塞代码。
请求体与数据校验
FastAPI 使用 Pydantic 模型声明请求体:
from pydantic import BaseModel, ConfigDict, Field
class SearchRequest(BaseModel):
model_config = ConfigDict(extra="forbid")
query: str = Field(min_length=1, max_length=4000)
top_k: int = Field(default=4, ge=1, le=10)
当路径操作接收 SearchRequest 时,FastAPI 会读取 JSON、调用 Pydantic 完成转换和校验,并把模型的 JSON Schema 加入 OpenAPI。字段约束可以限制长度、数值范围和格式;extra="forbid" 可以拒绝契约之外的字段。
请求模型解决的是输入边界校验。业务规则、权限判断以及需要访问外部系统的校验,通常仍应放在服务层或依赖中。
依赖注入
FastAPI 的依赖注入系统可以复用身份验证、权限检查、连接获取和公共参数处理:
from typing import Annotated
from fastapi import Depends
async def require_user() -> UserContext:
...
@app.get("/profile")
async def profile(
context: Annotated[UserContext, Depends(require_user)],
):
return context
依赖本身可以继续声明子依赖。例如,管理员依赖可以先调用用户依赖,再检查用户的权限等级。依赖产生的参数和安全要求也能进入 OpenAPI 描述。
依赖注入适合表达“执行路径操作前必须获得什么”。应用工厂参数或 app.state 则更适合在测试中替换服务对象、保存应用级共享状态。两种方式可以配合使用,但请求身份等逐请求数据不应放进跨请求共享的全局状态。
中间件与请求上下文
HTTP 中间件会包裹每一次请求和响应:
from uuid import uuid4
from fastapi import Request
@app.middleware("http")
async def request_context(request: Request, call_next):
request.state.request_id = str(uuid4())
response = await call_next(request)
response.headers["X-Request-ID"] = request.state.request_id
return response
中间件适合生成请求 ID、记录耗时、设置统一响应头或执行跨接口策略。request.state 可以保存当前请求链路的数据;它不同于 app.state,不会用于跨请求共享状态。
如果配置了多个中间件,它们会形成调用栈:请求阶段由外向内执行,响应阶段按相反方向返回。
异常与响应
FastAPI 对请求校验失败提供默认处理,也允许通过 @app.exception_handler()覆盖框架异常或处理业务异常:
from fastapi import Request
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
@app.exception_handler(RequestValidationError)
async def validation_error(
request: Request,
error: RequestValidationError,
):
return JSONResponse(
status_code=422,
content={
"code": "INVALID_INPUT",
"requestId": request.state.request_id,
},
)
自定义异常处理可以统一状态码和错误结构,也可以避免把请求体、凭据或内部异常信息直接暴露给客户端。
路径操作直接返回字典或 Pydantic 模型时,FastAPI 会生成 JSON 响应。需要精确控制状态码、响应头或响应内容时,可以直接返回 JSONResponse 等 Response 对象。
OpenAPI 与接口文档
FastAPI 根据路径、参数、请求模型和依赖自动生成 OpenAPI Schema 与交互式文档。
常见默认入口是:
/openapi.json:OpenAPI Schema;/docs:Swagger UI;/redoc:ReDoc。
这些路径可以在创建应用时调整,也可以关闭某个文档界面。自动生成文档并不意味着 API 契约已经完整:返回类型、状态码和错误响应如果没有显式描述,生成的 OpenAPI 可能无法完整反映真实行为。
应用生命周期与共享资源
数据库连接池、HTTP 客户端、机器学习模型等应用级资源通常需要在启动时创建、在关闭时释放。FastAPI 当前推荐使用 lifespan 管理这类生命周期。
简单的惰性初始化也可以把资源保存在 app.state,但并发初始化、失败恢复和关闭清理需要由应用自行处理。多进程部署时,每个 Worker 都有独立内存;进程内的 app.state 不会自动跨 Worker 共享。
运行与测试
FastAPI 是 ASGI 应用,需要由 Uvicorn 等 ASGI 服务器运行。Uvicorn 可以加载一个应用对象,也可以使用工厂模式调用返回 FastAPI 实例的函数。开发环境的自动重载不应直接当作生产运行策略。
FastAPI 的 TestClient基于 HTTPX,可以在不启动真实网络服务器的情况下测试完整的请求处理流程:
from fastapi.testclient import TestClient
def test_live():
with TestClient(create_app()) as client:
response = client.get("/health/live")
assert response.status_code == 200
应用工厂允许测试传入假的服务、认证器或存储,从而隔离外部系统。接口测试应覆盖正常响应、输入校验、身份权限、统一错误格式和就绪状态;TestClient 通过不等同于真实代理、网络和生产部署已经验收。