FastAPI - Organizing your code using APIRouter include_router

by
Jeremy Canfield |
Updated: January 17 2025
| FastAPI articles
Let's say you want to create an API that has 2 or more endpoints. In this scenario, it almost always make sense to use APIRouter include_router so that each endpoint has it's own dedicated file as a way to create a clean, well organized app. For example, let's say your app has the following structure.
├── main.py
├── api (directory)
│ ├── __init__.py
│ ├── foo.py
│ ├── bar.py
main.py could have something like this.
from fastapi import FastAPI
from api import foo, bar
app = FastAPI()
app.include_router(foo.router)
app.include_router(bar.router)
valid_endpoints = []
valid_endpoints += ['/api/foo']
valid_endpoints += ['/api/bar']
@app.post("/{rest_of_path:path}")
async def catch_all(rest_of_path: str):
if f"/{rest_of_path}" not in valid_endpoints:
message = f"/{rest_of_path} is NOT a valid endpoint. The valid endpoints are: {valid_endpoints}"
else:
message = f"/{rest_of_path} is a valid endpoint. The valid endpoints are: {valid_endpoints}"
return {"message": message}
api/__init__.py would be an empty file.
app/foo.py could have something like this.
from fastapi import APIRouter
router = APIRouter()
@router.post("/api/foo")
async def foo():
return { "message": "Hello from foo" }
app/bar.py could have something like this.
from fastapi import APIRouter
router = APIRouter()
@router.post("/api/bar")
async def bar():
return { "message": "Hello from bar" }
Did you find this article helpful?
If so, consider buying me a coffee over at