Routers
Let's learn how to organize a scalable FastAPI using APIRouter.
When building larger FastAPI applications, organizing your code becomes crucial.
Instead of putting all your endpoints into a single main.py
file, FastAPI provides APIRouter to help you structure your project in a clean and modular way.
In this post, we’ll walk through a real-world example of how to use routers effectively, including how to configure your API metadata and documentation URLs.
Why Use Routers?
Here’s why routers are essential in a real FastAPI project:
- Separation of concerns: Group related APIs together (e.g., model1 APIs, model2 APIs).
- Easier maintenance: Update or extend functionality without touching unrelated parts.
- Better scalability: As your API grows, routers make it easier to keep the project manageable.
- Cleaner documentation: Organized endpoints in your Swagger UI.
Example Project Structure
Suppose we have a project that serves two sets of APIs, model1
and model2
.
Here’s the structure:
1
2
3
4
5
/project-root
├── main.py
└── routers/
├── model1.py
└── model2.py
main.py
is the main application entry point.routers/model1.py
androuters/model2.py
contain router definitions for different parts of the API.
Main Application
Let’s look at the full code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import uvicorn
from fastapi import FastAPI
from routers import (
model1,
model2
)
tags_metadata = [
{"name": "Model1", "description": "Model1 API"},
{"name": "Model2", "description": "Model2 API"}
]
app = FastAPI(
title="Study API",
summary="LLM Service API",
version="1.0.0",
contact={
"name": "ds2man",
"email": "jaoneol@gmail.com",
"url": "ds2man.github.io"
},
openapi_tags=tags_metadata,
docs_url='/ds2man/docs',
redoc_url='/ds2man/redoc',
openapi_url='/ds2man/openapi.json'
)
# Register routers
app.include_router(model1.router, prefix="/ds2man/model1", tags=['Model1'])
app.include_router(model2.router, prefix="/ds2man/model2", tags=['Model2'])
if __name__ == "__main__":
access_port = 9248
uvicorn.run("main:app", host="127.0.0.1", port=access_port, reload=True)
Router Files
Each router file looks like this:
Example: routers/model1.py
and routers/model2.py
1
2
3
4
5
6
7
8
9
# routers/model1.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/info")
async def get_model1_info():
return {"model": "Model1", "description": "This is model1 information."}
1
2
3
4
5
6
7
8
9
# routers/model2.py
from fastapi import APIRouter
router = APIRouter()
@router.get("/info")
async def get_model2_info():
return {"model": "Model2", "description": "This is model2 information."}
Each router defines its own routes, independent of the main application.
Swagger UI
Conclusion
Using FastAPI Routers is a must if you want to build scalable and maintainable APIs.
By cleanly separating different parts of your service into routers, you make it easier for both you and your team to manage growth and complexity.