1. Pydantic 数据验证
- 核心作用:作为 FastAPI 数据流转的 "把关人",深度整合 Pydantic 库,让输入输出数据的合法性校验、类型转换等流程自动化且清晰可控。
- 数据解析与转换 :不管是前端发过来的 JSON 数据、URL 里的查询参数(query),还是表单(form)提交的数据,FastAPI 都会按照定义的 Pydantic 模型自动解析。比如前端传一个字符串 "12.3" 对应模型里的
price: float
字段,会自动转换成浮点数 12.3 ;若传了不满足模型定义的数据(像给name
传数字),会直接返回清晰的校验错误信息,告知哪里不符合规则。 - 复杂模型扩展 :除基础类型(str、float 等),还支持嵌套模型(比如一个
User
模型里包含Address
子模型 )、自定义验证函数(在 Pydantic 模型里写@validator
装饰的方法,校验字段特殊逻辑,如密码强度)、联合类型(字段可以是多种类型之一)等,灵活应对各类业务数据结构。
python
from pydantic import BaseModel, validator
class Address(BaseModel):
city: str
street: str
class User(BaseModel):
name: str
age: int
address: Address
@validator('age')
def check_age(cls, v):
if v < 18:
raise ValueError('Age must be at least 18')
return v
# 这样定义后,接口接收数据时,会层层校验,确保数据符合业务规则
2. 自动生成文档
- 文档类型与访问:
- Swagger UI(/docs):交互性强,能在线尝试发送请求(填参数、选请求方法等),实时看响应结果,很适合开发调试阶段,直观验证接口功能。界面是可视化的,有接口列表、每个接口的参数说明、请求示例等,像 "填表单" 一样测试接口。
- ReDoc(/redoc):文档排版更简洁清晰,侧重于展示接口的结构化定义,适合给团队里的后端、测试人员快速查阅接口规范,或者对外提供相对简洁的文档说明。
- 文档生成原理 :基于代码里的路径操作装饰器(
@app.get
等 )、参数注解、响应模型等信息,自动扫描并构建文档内容。只要按照 FastAPI 规范写接口,不用额外写文档配置,新接口加好后,刷新文档页面就自动更新,极大减少文档维护成本。比如定义了response_model=Item
,文档里就会清晰展示返回数据的结构、各字段类型和说明。
3. 依赖注入(Dependency Injection)
- 基础概念与优势 :把一些通用逻辑(如获取数据库连接、用户认证校验、权限检查 )提取成 "依赖",在需要的接口里通过
Depends
复用,让代码解耦,减少重复。比如多个接口都要检查用户是否登录且有权限,不用每个接口都写一遍校验逻辑,写一个依赖函数,接口里引用即可。 - 高级用法 - 依赖链与上下文管理:
- 依赖链 :可以多个依赖嵌套,比如接口依赖
get_user
,get_user
又依赖get_db
获取数据库连接查用户信息,形成清晰的逻辑调用链,方便排查问题和维护。 - 上下文管理(yield 用法) :像示例里
get_db
用yield
,在依赖开始时执行create_db()
获取连接,接口处理完请求后,会执行finally
里的db.close()
关闭连接,保证资源合理使用,尤其是数据库连接这类稀缺资源,避免泄漏。
- 依赖链 :可以多个依赖嵌套,比如接口依赖
python
from fastapi import Depends
# 模拟数据库操作类
class Database:
def connect(self):
return "DB Connection"
def close(self):
print("DB Closed")
def get_db():
db = Database().connect()
try:
yield db
finally:
Database().close()
# 依赖链示例,另一个依赖函数
def check_user(db=Depends(get_db)):
# 假设用 db 查用户信息做校验
return "Valid User"
@app.get("/protected")
def protected_route(user=Depends(check_user)):
return {"message": "Accessed with valid user", "user": user}
4. 路径操作函数(Path Operation Functions)
- 装饰器与请求方法映射 :
@app.get
对应 HTTP 的 GET 请求,用于获取资源;@app.post
对应 POST,常用来创建资源;还有@app.put
(更新资源 )、@app.delete
(删除资源 )等。通过装饰器,清晰定义接口的请求方式,让代码语义化。 - 参数来源与处理:
- path 参数 :像
"/items/{item_id}"
里的item_id
,直接从 URL 路径里提取,FastAPI 会根据注解的类型(如int
)自动转换,类型不匹配时返回 422 错误(请求数据无效)。 - query 参数 :如
q: str = None
,是 URL 里?q=xxx
这样的参数,可设置默认值(这里默认None
),也能设置必传(不设默认值且类型不为可选类型)。 - body 参数:一般用于 POST、PUT 等请求,接收前端发的 JSON 等数据,结合 Pydantic 模型校验,会自动解析成对应的模型对象。
- form、header 参数:分别从表单数据、请求头里提取,满足上传文件(结合表单)、校验请求头里的令牌(token)等特殊需求,丰富接口参数获取渠道。
- path 参数 :像
python
from fastapi import Form, Header
@app.post("/login")
def login(username: str = Form(...), password: str = Form(...), token: str = Header(None)):
# Form(...) 表示必传的表单参数,Header(None) 表示请求头里可选的 token 参数
return {"username": username, "token": token}
5. 响应模型(Response Model)
- 数据结构约束与过滤 :指定
response_model
后,FastAPI 会严格按照模型定义返回数据。比如实际返回的数据有额外字段(模型里没定义 ),会被自动过滤掉;若字段类型不匹配,会尝试转换(转换失败则报错 ),保证输出数据的规范性,让前端或其他调用方拿到符合预期的结构。 - 结合 Pydantic 高级特性 :支持模型里用
Optional
(可选字段 )、List
、Dict
等类型,还能嵌套其他模型。也可以用@model_validator
(Pydantic V2 语法 )等对返回数据做二次处理,比如统一格式化日期字段。
python
from pydantic import BaseModel
from datetime import datetime
class Product(BaseModel):
name: str
price: float
create_time: datetime
@model_validator(mode='after')
def format_create_time(self):
# 格式化时间字段,让返回更友好
self.create_time = self.create_time.strftime("%Y-%m-%d %H:%M:%S")
return self
@app.get("/product", response_model=Product)
def get_product():
return {"name": "Book", "price": 20.5, "create_time": datetime.now()}
# 返回的 create_time 会是格式化后的字符串
6. 异步支持(async/await)
- 异步原理与适用场景 :基于 Python 的异步 IO 特性,当接口里有像数据库查询(用异步数据库驱动 )、网络请求(如
aiohttp
发异步请求 )这类 I/O 操作时,用async def
定义视图函数,配合await
关键字,让程序在等待 I/O 结果时不阻塞,去处理其他请求,大幅提升高并发场景下的性能,特别适合开发 Web API 服务应对大量客户端请求。 - 与同步代码的混用 :如果有一些老的同步库(没有异步版本 )要在接口里用,FastAPI 也支持在异步函数里通过
loop.run_in_executor
等方式,把同步操作放到线程池执行,避免阻塞事件循环,不过这种情况要注意线程安全问题(比如操作共享资源 )。
python
import asyncio
import requests
from concurrent.futures import ThreadPoolExecutor
@app.get("/sync-in-async")
async def sync_in_async():
# 用线程池执行同步的 requests 请求
with ThreadPoolExecutor() as executor:
loop = asyncio.get_running_loop()
result = await loop.run_in_executor(executor, lambda: requests.get("https://example.com").text)
return {"result": result}
7. 中间件(Middleware)
- 执行流程与作用:中间件是在请求到达路由处理函数之前、以及响应返回给客户端之前执行的代码逻辑。可以对请求和响应做统一处理,比如:
- 日志记录:记录每个请求的路径、方法、耗时、状态码等,方便排查问题和做统计分析。
- 跨域支持(CORS) :通过中间件统一设置响应头(如
Access-Control-Allow-Origin
等 ),解决前端跨域请求的问题,不用每个接口单独处理。 - 请求预处理:检查请求头里的特定标识、对请求参数做初步过滤(如防 SQL 注入简单处理 )。
- 自定义中间件示例 :除了用
@app.middleware
装饰器,还能自己定义中间件类,更灵活控制逻辑。比如记录请求耗时的中间件:
python
from fastapi import Request
import time
class TimingMiddleware:
def __init__(self, app):
self.app = app
async def __call__(self, request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
print(f"Request to {request.url.path} took {process_time} seconds")
return response
# 在 FastAPI 应用里注册
app.add_middleware(TimingMiddleware)
8. 异常处理(Exception Handling)
- 内置异常与自定义:
- HTTPException :是 FastAPI 内置的异常类,抛出后会返回对应的 HTTP 状态码和错误详情(
detail
),比如HTTPException(status_code=404, detail="Item not found")
,前端能清晰拿到错误信息做提示。 - 自定义全局异常处理器 :可以用
@app.exception_handler
装饰器,捕获特定异常(如自定义的业务异常BusinessException
)或者通用异常(如Exception
),统一返回格式。这样不管哪里抛出异常,都能按照设定的结构返回给调用方,让错误处理更规范。
- HTTPException :是 FastAPI 内置的异常类,抛出后会返回对应的 HTTP 状态码和错误详情(
python
from fastapi import HTTPException, status
from fastapi.responses import JSONResponse
class BusinessException(Exception):
def __init__(self, error_code, error_msg):
self.error_code = error_code
self.error_msg = error_msg
@app.exception_handler(BusinessException)
async def business_exception_handler(request: Request, exc: BusinessException):
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={"error_code": exc.error_code, "error_msg": exc.error_msg}
)
@app.get("/business-error")
def business_error_route():
raise BusinessException(1001, "Custom business error occurred")
9. 认证与授权(Security)
- OAuth2 与 JWT 集成:
- OAuth2PasswordBearer :是常用的一种安全机制,指定
tokenUrl
(用户登录获取令牌的接口路径 ),接口里通过Depends(oauth2_scheme)
获取请求里的令牌(通常在请求头Authorization
里 ),然后自己写逻辑校验令牌合法性(比如解析 JWT 令牌,检查签名、过期时间等 ),实现登录态保护,让需要权限的接口只能被合法用户访问。 - JWT 校验细节 :结合
python-jose
等库,把用户信息(如用户 ID、用户名、权限角色 )加密到 JWT 令牌里,在依赖函数里解析令牌,验证通过后把用户信息提取出来,方便接口里做权限判断(比如某些接口只有管理员角色能访问 )。
- OAuth2PasswordBearer :是常用的一种安全机制,指定
python
from fastapi.security import OAuth2PasswordBearer
from jose import JWTError, jwt
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
# 模拟 JWT 密钥和算法
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
async def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise credentials_exception
# 这里可以根据 username 查数据库获取完整用户信息
return {"username": username}
except JWTError:
raise credentials_exception
@app.get("/protected-by-jwt")
def protected_route(user=Depends(get_current_user)):
return {"message": "Accessed by valid user", "user": user}
10. 性能优异 & Uvicorn 支持
- 基于 Starlette 的底层优势:FastAPI 构建在 Starlette 之上,Starlette 本身对异步处理、请求路由等做了高效实现,让 FastAPI 能高效处理大量并发请求,性能比肩 Go、Node.js 等语言开发的 Web 框架,官方有性能测试数据对比,在高并发场景下响应更快、资源占用更合理。
- Uvicorn 部署细节:
- 开发环境 :用
uvicorn main:app --reload
启动,--reload
开启自动重载,代码修改后不用手动重启服务,方便开发调试。 - 生产环境 :去掉
--reload
,可以结合gunicorn
做进程管理(比如gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app
,-w
指定工作进程数,充分利用多核 CPU ),提升生产环境的吞吐量和稳定性,同时要注意配置日志、监控等,保障服务可靠运行。 - 性能调优 :还可以通过调整 Uvicorn 的
--loop
(选择更高效的事件循环,如uvloop
,需额外安装 )、--timeout-keep-alive
(设置连接保持超时时间 )等参数,进一步优化性能,适配不同业务场景需求。
- 开发环境 :用
python
# 安装 uvloop 提升性能(可选)
pip install uvloop
# 生产环境结合 gunicorn 启动示例
gunicorn -w 4 -k uvicorn.workers.UvicornWorker -b 0.0.0.0:8000 main:app
通过上述对每个知识点的细致拆解,能更全面、深入理解 FastAPI 的设计理念和实际应用要点,助力开发者在项目里更好运用它构建高性能、易用的 Web API 。