如何将Python装饰器式API路由方法拆分到不同文件中
解决方案:拆分装饰器路由到独立文件的标准实现
针对AWS Lambda Powertools(及同类装饰器路由框架)中拆分模块路由的问题,以下是无循环依赖、逻辑内聚、结构清晰的标准实现方案:
项目结构调整
先整理出分层清晰的目录结构,将路由实例、单个HTTP方法的处理逻辑完全分离:
invoices/ ├── adapters/ │ └── api/ │ ├── routes/ │ │ ├── __init__.py │ │ ├── invoices_router.py # 仅定义路由实例 │ │ ├── get_invoice.py # GET /invoices/<id> 逻辑 │ │ └── post_invoice.py # POST /invoices 逻辑 │ └── api.py # API入口文件
1. 单独定义路由实例文件
创建invoices_router.py,仅初始化Router实例,不导入任何处理函数,从根源避免循环依赖:
# invoices/adapters/api/routes/invoices_router.py from aws_lambda_powertools.event_handler import Router # 全局路由实例,供所有处理函数文件导入 invoices_router = Router()
2. 单个HTTP方法的逻辑与路由绑定
在独立文件中编写处理逻辑,直接导入路由实例并用装饰器绑定,保持逻辑与路由的关联性:
GET方法示例(get_invoice.py)
# invoices/adapters/api/routes/get_invoice.py from .invoices_router import invoices_router @invoices_router.get("/<invoice_id>", tags=["Invoices"]) def handle_get_invoice(invoice_id: str): # 这里写具体的业务逻辑 return {"invoice_id": invoice_id, "status": "retrieved"}
POST方法示例(post_invoice.py)
# invoices/adapters/api/routes/post_invoice.py from .invoices_router import invoices_router @invoices_router.post("/", tags=["Invoices"]) def handle_post_invoice(): # 这里写具体的业务逻辑 return {"status": "invoice created"}
3. 路由模块统一导出
在routes/__init__.py中导入所有处理函数文件(触发装饰器注册路由),同时导出路由实例,供入口文件调用:
# invoices/adapters/api/routes/__init__.py # 导入所有处理函数,自动执行装饰器完成路由注册 from . import get_invoice, post_invoice # 导出路由实例,简化入口文件的导入路径 from .invoices_router import invoices_router
4. 入口文件保持简洁
原有的api.py无需修改,直接导入统一导出的路由实例即可:
# invoices/adapters/api/api.py from aws_lambda_powertools.event_handler import APIGatewayRestResolver from invoices.adapters.api.routes import invoices_router app = APIGatewayRestResolver(enable_validation=True) app.include_router(invoices_router, prefix="/invoices") def lambda_handler(event, context): return app.resolve(event, context)
方案优势
- 无循环依赖:路由实例与处理函数单向导入,彻底解决循环引用问题
- 逻辑内聚:每个HTTP方法的路由规则和业务逻辑在同一文件,避免逻辑分离
- 扩展性强:新增PUT/DELETE等方法时,只需新增对应文件并在
__init__.py中导入即可 - 结构清晰:路由实例、处理逻辑、入口分层明确,便于维护
内容的提问来源于stack exchange,提问作者victorperezpiqueras
相关产品推荐
相关产品推荐

