Python 后端基础(十二):FastAPI 工程化,依赖注入、Pydantic、异常处理和中间件怎么用
2026/7/1 21:26:33 网站建设 项目流程

FastAPI 写一个 demo 很快,但项目要像样,不能所有代码都堆在 `main.py`。

工程化的 FastAPI 项目,要考虑分层、依赖注入、配置管理、异常处理、中间件、日志、数据库连接和测试。

【一、什么叫工程化】

工程化不是把项目写复杂,而是让项目在多人协作、需求变化、出错排查、上线部署时仍然可维护。

一个 demo 默认一切顺利:

参数一定正确

数据库一定能连上

外部 API 一定返回成功

用户不会乱传数据

工程化项目正好相反:

参数可能错

数据库可能断

模型 API 可能超时

用户可能没权限

任务可能失败

日志必须能查

【二、推荐项目结构】

小型 FastAPI 项目可以这样拆:

app/

main.py

api/

users.py

tasks.py

schemas/

user.py

services/

user_service.py

repositories/

user_repo.py

core/

config.py

security.py

db/

session.py

大概职责:

- api:接收请求,返回响应。

- schemas:Pydantic 请求和响应模型。

- services:业务逻辑。

- repositories:数据库访问。

- core:配置、安全、工具。

- db:数据库连接。

【三、依赖注入是什么】

FastAPI 的 `Depends` 可以把公共逻辑抽出来。

比如获取当前用户:

from fastapi import Depends, HTTPException

def get_current_user(token: str):

user = parse_token(token)

if not user:

raise HTTPException(status_code=401, detail="未登录")

return user

@app.get("/me")

def me(current_user=Depends(get_current_user)):

return current_user

这样每个需要登录的接口都可以复用 `get_current_user`。

依赖注入常用于:

- 获取数据库连接。

- 获取当前用户。

- 校验权限。

- 注入配置。

- 注入第三方客户端。

【四、Pydantic 模型怎么分】

不要一个模型到处用。

例如用户相关可以拆成:

class UserCreate(BaseModel):

username: str

password: str

class UserLogin(BaseModel):

username: str

password: str

class UserOut(BaseModel):

id: int

username: str

注意 `UserOut` 不应该包含 `password` 或 `password_hash`。

请求模型和响应模型分开,是后端安全和维护的基本习惯。

【五、统一异常处理】

项目里不要到处返回杂乱错误。

可以统一异常结构:

{

"code": "USER_NOT_FOUND",

"message": "用户不存在"

}

FastAPI 可以注册异常处理器:

from fastapi import Request

from fastapi.responses import JSONResponse

class BizError(Exception):

def __init__(self, code: str, message: str):

self.code = code

self.message = message

@app.exception_handler(BizError)

async def biz_error_handler(request: Request, exc: BizError):

return JSONResponse(

status_code=400,

content={"code": exc.code, "message": exc.message},

)

这样业务层可以直接抛 `BizError`。

【六、中间件是什么】

中间件是在请求进入接口前、响应返回客户端前执行的一层逻辑。

常见用途:

- 记录请求日志。

- 统计接口耗时。

- 处理跨域 CORS。

- 统一添加响应头。

- 追踪 request_id。

示例:

import time

from fastapi import Request

@app.middleware("http")

async def log_requests(request: Request, call_next):

start = time.time()

response = await call_next(request)

cost = time.time() - start

print(request.method, request.url.path, cost)

return response

生产项目里建议用 logging,不要直接 print。

【七、配置管理】

不要把数据库密码、JWT 密钥写死在代码里。

推荐用环境变量:

from pydantic_settings import BaseSettings

class Settings(BaseSettings):

database_url: str

jwt_secret: str

class Config:

env_file = ".env"

settings = Settings()

`.env` 不要上传 GitHub,`.env.example` 可以上传示例。

【八、测试怎么写】

FastAPI 可以用 `TestClient` 测接口。

from fastapi.testclient import TestClient

from app.main import app

client = TestClient(app)

def test_health():

resp = client.get("/health")

assert resp.status_code == 200

有测试的项目,比只有截图的项目更有工程化说服力。

【九、常见坑】

- 所有代码堆在一个文件。

- 数据库连接在每个接口里重复创建。

- 配置写死,密钥上传 GitHub。

- 只写 happy path,不处理异常。

- 没有日志,出问题只能猜。

- 请求模型和响应模型混用,泄漏敏感字段。

【十、面试常问】

1. FastAPI 的 Depends 有什么用?

Depends 用于依赖注入,可以复用公共逻辑,例如数据库连接、当前用户、权限校验、配置对象等,减少重复代码。

2. 中间件适合做什么?

适合处理请求级别的通用逻辑,比如日志、耗时统计、CORS、request_id、鉴权前置处理等。不适合把复杂业务逻辑都塞进中间件。

3. FastAPI 项目如何分层?

常见分层是 API 层处理请求响应,Schema 层定义数据结构,Service 层写业务逻辑,Repository 层访问数据库,Core 层管理配置和安全工具。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询