FastAPI中如何在嵌套路由中包含路径参数?
在FastAPI中嵌套APIRouter并传递路径参数前缀的解决方案
问题概述
需要实现组织与用户的嵌套CRUD路由:组织端点路径为/api/latest/org/{org_id},用户端点路径为/api/latest/org/{org_id}/users/{user_id},同时要避免用户路由与组织路径硬编码耦合。此前尝试在用户路由前缀中直接写入/org/{org_id}/users时,触发AssertionError: Path params must be of one of the supported types错误。
错误原因
- 路径参数未声明类型:FastAPI要求所有路径参数必须明确指定类型(如
int、str),否则会触发断言校验失败。 - 路由前缀重复定义:用户路由硬编码组织路径前缀,违背了嵌套路由的解耦设计思路。
解决方案
通过分层嵌套路由实现:先定义带组织路径参数的父路由,再将用户路由嵌套到父路由下,自动继承父路由的路径前缀与参数。
1. 定义组织路由(organization.py)
from fastapi import APIRouter # 明确指定org_id的类型为int,避免参数类型校验错误 org_router = APIRouter(prefix="/org/{org_id:int}") @org_router.get("/") async def get_organization(org_id: int): return {"org_id": org_id, "name": f"Organization {org_id}"} @org_router.post("/") async def create_organization(org_id: int, name: str): return {"org_id": org_id, "name": name} @org_router.put("/") async def update_organization(org_id: int, name: str): return {"org_id": org_id, "updated_name": name} @org_router.delete("/") async def delete_organization(org_id: int): return {"deleted_org_id": org_id}
2. 定义用户路由(user.py)
仅关注自身的路径前缀,无需硬编码组织相关路径:
from fastapi import APIRouter user_router = APIRouter(prefix="/users") @user_router.get("/{user_id:int}") async def get_user(org_id: int, user_id: int): return {"org_id": org_id, "user_id": user_id, "username": f"user_{user_id}"} @user_router.post("/{user_id:int}") async def create_user(org_id: int, user_id: int, username: str): return {"org_id": org_id, "user_id": user_id, "username": username} @user_router.put("/{user_id:int}") async def update_user(org_id: int, user_id: int, username: str): return {"org_id": org_id, "user_id": user_id, "updated_username": username} @user_router.delete("/{user_id:int}") async def delete_user(org_id: int, user_id: int): return {"org_id": org_id, "deleted_user_id": user_id}
3. 嵌套路由并生成主路由(endpoints/init.py)
from fastapi import APIRouter from .organization import org_router from .user import user_router # 将用户路由嵌套到组织路由下,自动继承/org/{org_id}前缀 org_router.include_router(user_router) # 定义全局前缀 main_router = APIRouter(prefix="/api/latest") main_router.include_router(org_router)
4. 挂载主路由到应用(main.py)
from fastapi import FastAPI from web_app.endpoints import main_router app = FastAPI() app.include_router(main_router)
验证结果
最终生成的端点完全符合需求:
- 组织端点:
GET /api/latest/org/{org_id}POST /api/latest/org/{org_id}PUT /api/latest/org/{org_id}DELETE /api/latest/org/{org_id} - 用户端点:
GET /api/latest/org/{org_id}/users/{user_id}POST /api/latest/org/{org_id}/users/{user_id}PUT /api/latest/org/{org_id}/users/{user_id}DELETE /api/latest/org/{org_id}/users/{user_id}
后续若需修改组织路径前缀(如将/org改为/organizations),仅需修改org_router的prefix参数即可,无需改动用户路由代码,实现了解耦。
内容的提问来源于stack exchange,提问作者Henry Thomas
相关产品推荐
相关产品推荐

