路由与请求处理
FastAPI 的路由是“声明式”的:参数类型即校验,返回值类型即文档。面试主线:三类参数怎么拿、状态码怎么控、大型项目怎么组织路由。
三类参数
@app.get("/users/{user_id}") # 1. 路径参数
def get_user(user_id: int, # 类型转换+校验(非 int 返回 422)
verbose: bool = False, # 2. 查询参数(带默认值可选)
tag: str | None = None): # 可选查询参数
return {"id": user_id, "verbose": verbose, "tag": tag}
@app.post("/users") # 3. 请求体
def create_user(user: UserCreate): # Pydantic 模型自动解析+校验
...| 参数来源 | 声明方式 | 说明 |
|---|---|---|
| 路径参数 | 路径模板 {id} |
类型注解决定转换和校验 |
| 查询参数 | 函数参数(非路径模板) | 默认值决定可选性 |
| 请求体 | Pydantic 模型类型 | 自动 JSON 解析、校验、422 |
| 请求头/COOKIE | Header() / Cookie() |
显式声明 |
路径参数顺序无关,按名字匹配;/users/{user_id} 和 /users/me 共存时,静态路由优先匹配。
状态码与响应
from fastapi import status
@app.post("/users", status_code=status.HTTP_201_CREATED)
def create_user(user: UserCreate) -> UserOut: # 响应模型
...
@app.get("/users/{user_id}", responses={404: {"description": "用户不存在"}})
def get_user(user_id: int):
...status_code:默认响应状态码- 响应模型
-> UserOut:自动过滤字段(隐藏密码等敏感字段)、序列化、生成文档 JSONResponse/Response直接控制响应体;raise HTTPException(404, ...)抛业务错误
APIRouter 模块化
大项目按资源拆分:
# app/routers/users.py
router = APIRouter(prefix="/users", tags=["users"])
@router.get("/{user_id}")
def get_user(user_id: int):
...
# app/main.py
from app.routers import users
app.include_router(users.router) # 挂载, 支持多个prefix:统一路径前缀(/users),路由函数里不再重复写tags:OpenAPI 文档分组- 每个模块独立文件,main.py 只做组装
面试追问
- 路径参数和查询参数怎么区分? 路径模板里的
{id}是路径参数,普通函数参数是查询参数。类型注解决定校验 - 请求体怎么校验? Pydantic 模型作为参数类型,自动解析 JSON、校验、非法返回 422
- 响应模型有什么用? 类型即契约:自动序列化、过滤字段(响应中隐藏密码)、生成 OpenAPI 文档
- APIRouter 解决什么? 模块化:prefix 统一前缀、tags 文档分组、main.py 只组装
- 状态码怎么自定义? status_code 参数、HTTPException 抛错、responses 声明文档