FastAPI 依賴注入最佳實踐
依賴設計
- 保持依賴函數簡潔明確
- 使用依賴層次結構
- 使用類作為依賴
- 使用 Pydantic 模型進行配置管理
性能優化
- 緩存重複使用的依賴: 對於計算成本高但結果不常變化的依賴,使用緩存可以提高性能。
- 避免不必要的依賴嵌套: 過度嵌套的依賴可能導致性能問題和難以跟踪的錯誤。
測試
- 設計便於測試的依賴:依賴應該易於在測試中替換或模擬。
- 使用依賴覆蓋進行測試: FastAPI 提供了依賴覆蓋機制,使得測試變得簡單。
- 使用工廠模式簡化測試配置: 工廠模式可以幫助你在測試中更容易地創建和配置依賴。
安全性
- 分層身份驗證依賴: 構建分層的身份驗證依賴,以實現更精細的訪問控制。
- 安全地處理敏感配置: 確保敏感配置不會被意外暴露。
組織和結構
1. 按功能組織依賴
將相關的依賴組織在一起,以提高可維護性。
project/
├── app/
│ ├── __init__.py
│ ├── main.py
│ ├── dependencies/
│ │ ├── __init__.py
│ │ ├── database.py # 資料庫依賴
│ │ ├── auth.py # 身份驗證依賴
│ │ ├── services.py # 外部服務依賴
│ │ └── commons.py # 通用依賴
│ ├── routers/
│ │ ├── __init__.py
│ │ ├── users.py
│ │ └── items.py
│ └── ...
在 dependencies/__init__.py
中導出常用依賴:
# dependencies/__init__.py
from .database import get_db
from .auth import get_current_user, get_active_user
from .services import get_email_service, get_payment_service
__all__ = [
"get_db",
"get_current_user",
"get_active_user",
"get_email_service",
"get_payment_service"
]
2. 使用依賴容器
對於大型應用,考慮使用依賴容器來管理複雜的依賴關係。
from fastapi import Depends
class Container:
def __init__(self):
self._services = {}
def register(self, name, factory):
self._services[name] = factory
def resolve(self, name):
if name not in self._services:
raise ValueError(f"Service {name} not registered")
factory = self._services[name]
return factory()
# 創建全局容器
container = Container()
# 註冊服務
container.register("db", get_db)
container.register("user_repository", lambda: UserRepository(next(container.resolve("db"))))
container.register("auth_service", lambda: AuthService(container.resolve("user_repository")))
# 依賴函數
def get_auth_service():
return container.resolve("auth_service")
@app.get("/users/me")
def read_users_me(auth_service = Depends(get_auth_service)):
current_user = auth_service.get_current_user()
return current_user
這種方法在大型應用中特別有用,可以集中管理依賴關係。
常見陷阱與如何避免
1. 循環依賴
循環依賴是一個常見問題,可能導致難以診斷的錯誤。
- 解決方案:
- 重構依賴關係,消除循環
- 使用延遲初始化或工廠模式
2. 過度使用全局狀態
過度依賴全局狀態會使應用難以測試和維護。
- 解決方案: 使用適當的生命週期管理和依賴注入,而不是全局變數。
3. 忽略資源清理
未能正確清理資源可能導致資源洩漏
- 解決方案: 使用上下文管理器或
yield
依賴確保資源被適當清理。
依賴注入進階技巧
- 條件依賴: 根據條件選擇不同的依賴實現。
- 參數化依賴: 創建可接受參數的依賴,以增加靈活性。
- 動態依賴解析: 在運行時動態選擇依賴。
關鍵要點回顧
- 保持依賴簡單明確:每個依賴應該有一個明確的目的
- 構建依賴層次結構:使用分層方法組織依賴
- 優化性能:適當使用緩存和避免不必要的依賴嵌套
- 設計便於測試的依賴:使依賴易於在測試中替換或模擬
- 安全處理敏感配置:確保敏感信息不被意外暴露
- 組織良好的代碼結構:按功能組織依賴,提高可維護性