How can I include one APIRouter inside another AND specify that some path param is a required prefix?
For context: Let's say I have the concept of an organization and a user. A user only belongs to one organization. My web app could be structured as follows:
├── web_app
├── endpoints
├── __init__.py # produces main_router by including other routers inside each other
├── organization.py # contains endpoints relevant to the organization
├── user.py # contains endpoints relevant to the user
└── main.py # includes main_router in app
Let's assume I want to achieve basic CRUD functionality for organizations and users. My endpoints could look something like this:
For orgs:
GET /api/latest/org/{org_id}
POST /api/latest/org/{org_id}
PUT /api/latest/org/{org_id}
DELETE /api/latest/org/{org_id}
For users:
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}
Since users are nested under orgs, within user.py, I could write all of my endpoints like this:
user_router = APIRouter()
@user_router.get("/org/{org_id}/users/{user_id}")
async def get_user(org_id, user_id):
...
But that gets gross really quick. The user_router is completely disjointed from the org_router even though one should be nested inside the other. If I make a change to the org router, I now need to change every single user router endpoint. God forbid I have something nested under users....
So as per my question, I was hoping something like this would work:
# user.py
user_router = APIRouter(prefix="/org/{org_id}/users")
@user_router.get("/{user_id}")
async def get_user(org_id, user_id):
# __init__.py
org_router.include_router(user_router)
main_router = APIRouter(prefix="/api/latest/")
main_router.include_router(org_router)
but that gives me the following error:
AssertionError: Path params must be of one of the supported types. I don't get the error if I remove {org_id} from the prefix, so I know APIRouter(prefix="/org/{org_id}/users") is the problem.
This is the only documentation we get from FastAPI on the matter: https://fastapi.tiangolo.com/tutorial/bigger-applications/#include-an-apirouter-in-another
Is what I'm looking for even possible? This seems like an extremely common situation so I'm curious what other folks do.