0
# API Routing
1
2
APIRouter allows organizing and grouping related API endpoints with shared configuration, middleware, and dependencies. Routers enable modular API design and can be included in the main FastAPI application or nested within other routers.
3
4
## Capabilities
5
6
### APIRouter Class
7
8
Router for organizing related endpoints with shared configuration including URL prefixes, tags, dependencies, and response models.
9
10
```python { .api }
11
class APIRouter:
12
def __init__(
13
self,
14
*,
15
prefix: str = "",
16
tags: List[str] = None,
17
dependencies: List[Depends] = None,
18
default_response_class: Type[Response] = Default(JSONResponse),
19
responses: dict = None,
20
callbacks: List[BaseRoute] = None,
21
routes: List[BaseRoute] = None,
22
redirect_slashes: bool = True,
23
default: ASGIApp = None,
24
dependency_overrides_provider: Any = None,
25
route_class: Type[APIRoute] = APIRoute,
26
on_startup: List[Callable] = None,
27
on_shutdown: List[Callable] = None,
28
lifespan: Lifespan = None,
29
deprecated: bool = None,
30
include_in_schema: bool = True,
31
generate_unique_id_function: Callable[[APIRoute], str] = Default(generate_unique_id),
32
**kwargs: Any,
33
) -> None:
34
"""
35
Create an APIRouter instance.
36
37
Parameters:
38
- prefix: Common URL prefix for all routes in this router
39
- tags: List of tags for grouping routes in documentation
40
- dependencies: List of dependencies applied to all routes
41
- default_response_class: Default response class for all routes
42
- responses: Additional response models for all routes
43
- callbacks: List of callback routes
44
- routes: List of routes to include in the router
45
- deprecated: Mark all routes as deprecated
46
- include_in_schema: Include router routes in OpenAPI schema
47
"""
48
```
49
50
### HTTP Method Decorators
51
52
Decorators for defining API endpoints on the router with the same functionality as FastAPI application decorators.
53
54
```python { .api }
55
def get(
56
self,
57
path: str,
58
*,
59
response_model: Any = Default(None),
60
status_code: int = None,
61
tags: List[str] = None,
62
dependencies: List[Depends] = None,
63
summary: str = None,
64
description: str = None,
65
response_description: str = "Successful Response",
66
responses: dict = None,
67
deprecated: bool = None,
68
operation_id: str = None,
69
response_model_include: IncEx = None,
70
response_model_exclude: IncEx = None,
71
response_model_by_alias: bool = True,
72
response_model_exclude_unset: bool = False,
73
response_model_exclude_defaults: bool = False,
74
response_model_exclude_none: bool = False,
75
include_in_schema: bool = True,
76
response_class: Type[Response] = Default(JSONResponse),
77
name: str = None,
78
callbacks: List[BaseRoute] = None,
79
openapi_extra: dict = None,
80
generate_unique_id_function: Callable[[APIRoute], str] = Default(generate_unique_id),
81
) -> Callable[[DecoratedCallable], DecoratedCallable]:
82
"""
83
Decorator for GET endpoints on this router.
84
85
Parameters same as FastAPI.get() decorator.
86
"""
87
88
def post(self, path: str, **kwargs) -> Callable[[DecoratedCallable], DecoratedCallable]:
89
"""Decorator for POST endpoints on this router."""
90
91
def put(self, path: str, **kwargs) -> Callable[[DecoratedCallable], DecoratedCallable]:
92
"""Decorator for PUT endpoints on this router."""
93
94
def delete(self, path: str, **kwargs) -> Callable[[DecoratedCallable], DecoratedCallable]:
95
"""Decorator for DELETE endpoints on this router."""
96
97
def patch(self, path: str, **kwargs) -> Callable[[DecoratedCallable], DecoratedCallable]:
98
"""Decorator for PATCH endpoints on this router."""
99
100
def head(self, path: str, **kwargs) -> Callable[[DecoratedCallable], DecoratedCallable]:
101
"""Decorator for HEAD endpoints on this router."""
102
103
def options(self, path: str, **kwargs) -> Callable[[DecoratedCallable], DecoratedCallable]:
104
"""Decorator for OPTIONS endpoints on this router."""
105
106
def trace(self, path: str, **kwargs) -> Callable[[DecoratedCallable], DecoratedCallable]:
107
"""Decorator for TRACE endpoints on this router."""
108
109
def websocket(
110
self,
111
path: str,
112
*,
113
name: str = None,
114
dependencies: List[Depends] = None,
115
) -> Callable[[DecoratedCallable], DecoratedCallable]:
116
"""Decorator for WebSocket endpoints on this router."""
117
```
118
119
### Router Composition
120
121
Methods for including sub-routers and adding routes programmatically to create hierarchical API structures.
122
123
```python { .api }
124
def include_router(
125
self,
126
router: APIRouter,
127
*,
128
prefix: str = "",
129
tags: List[str] = None,
130
dependencies: List[Depends] = None,
131
default_response_class: Type[Response] = Default(JSONResponse),
132
responses: dict = None,
133
callbacks: List[BaseRoute] = None,
134
deprecated: bool = None,
135
include_in_schema: bool = True,
136
generate_unique_id_function: Callable[[APIRoute], str] = Default(generate_unique_id),
137
) -> None:
138
"""
139
Include another APIRouter in this router.
140
141
Parameters:
142
- router: APIRouter instance to include
143
- prefix: Additional URL prefix for the included router
144
- tags: Additional tags for all routes in the included router
145
- dependencies: Additional dependencies for all routes
146
- responses: Additional response models
147
- deprecated: Mark all included routes as deprecated
148
- include_in_schema: Include routes in OpenAPI schema
149
"""
150
151
def add_api_route(
152
self,
153
path: str,
154
endpoint: Callable,
155
*,
156
methods: List[str] = None,
157
name: str = None,
158
response_model: Any = Default(None),
159
status_code: int = None,
160
tags: List[str] = None,
161
dependencies: List[Depends] = None,
162
summary: str = None,
163
description: str = None,
164
response_description: str = "Successful Response",
165
responses: dict = None,
166
deprecated: bool = None,
167
operation_id: str = None,
168
response_model_include: IncEx = None,
169
response_model_exclude: IncEx = None,
170
response_model_by_alias: bool = True,
171
response_model_exclude_unset: bool = False,
172
response_model_exclude_defaults: bool = False,
173
response_model_exclude_none: bool = False,
174
include_in_schema: bool = True,
175
response_class: Type[Response] = Default(JSONResponse),
176
callbacks: List[BaseRoute] = None,
177
openapi_extra: dict = None,
178
generate_unique_id_function: Callable[[APIRoute], str] = Default(generate_unique_id),
179
) -> None:
180
"""
181
Add an API route programmatically to this router.
182
183
Parameters same as FastAPI.add_api_route() method.
184
"""
185
186
def add_api_websocket_route(
187
self,
188
path: str,
189
endpoint: Callable,
190
*,
191
name: str = None,
192
dependencies: List[Depends] = None,
193
) -> None:
194
"""
195
Add a WebSocket route programmatically to this router.
196
197
Parameters same as FastAPI.add_api_websocket_route() method.
198
"""
199
```
200
201
### Route Mounting
202
203
Method for mounting ASGI applications and static file servers.
204
205
```python { .api }
206
def mount(
207
self,
208
path: str,
209
app: ASGIApp,
210
*,
211
name: str = None,
212
) -> None:
213
"""
214
Mount an ASGI application at the given path.
215
216
Parameters:
217
- path: URL path where the application should be mounted
218
- app: ASGI application to mount
219
- name: Name for the mount (for URL generation)
220
"""
221
```
222
223
### Route Classes
224
225
Individual route representation classes used internally by APIRouter.
226
227
```python { .api }
228
class APIRoute:
229
"""
230
Individual API route representation with all route metadata,
231
path parameters, dependencies, and response models.
232
"""
233
def __init__(
234
self,
235
path: str,
236
endpoint: Callable,
237
*,
238
response_model: Any = Default(None),
239
status_code: int = None,
240
tags: List[str] = None,
241
dependencies: List[Depends] = None,
242
summary: str = None,
243
description: str = None,
244
response_description: str = "Successful Response",
245
responses: dict = None,
246
deprecated: bool = None,
247
name: str = None,
248
methods: List[str] = None,
249
operation_id: str = None,
250
response_model_include: IncEx = None,
251
response_model_exclude: IncEx = None,
252
response_model_by_alias: bool = True,
253
response_model_exclude_unset: bool = False,
254
response_model_exclude_defaults: bool = False,
255
response_model_exclude_none: bool = False,
256
include_in_schema: bool = True,
257
response_class: Type[Response] = Default(JSONResponse),
258
callbacks: List[BaseRoute] = None,
259
generate_unique_id_function: Callable[[APIRoute], str] = Default(generate_unique_id),
260
openapi_extra: dict = None,
261
) -> None: ...
262
263
class APIWebSocketRoute:
264
"""
265
WebSocket route representation for real-time communication endpoints.
266
"""
267
def __init__(
268
self,
269
path: str,
270
endpoint: Callable,
271
*,
272
name: str = None,
273
dependencies: List[Depends] = None,
274
) -> None: ...
275
```
276
277
## Usage Examples
278
279
### Basic Router Usage
280
281
```python
282
from fastapi import APIRouter, FastAPI
283
284
# Create router for user-related endpoints
285
users_router = APIRouter(
286
prefix="/users",
287
tags=["users"],
288
responses={404: {"description": "Not found"}}
289
)
290
291
@users_router.get("/")
292
def get_users():
293
return [{"username": "john"}, {"username": "jane"}]
294
295
@users_router.get("/{user_id}")
296
def get_user(user_id: int):
297
return {"user_id": user_id, "username": "john"}
298
299
@users_router.post("/")
300
def create_user(user: dict):
301
return {"message": "User created", "user": user}
302
303
# Include router in main application
304
app = FastAPI()
305
app.include_router(users_router)
306
```
307
308
### Router with Dependencies
309
310
```python
311
from fastapi import APIRouter, Depends, HTTPException
312
313
def get_current_user():
314
# Authentication logic here
315
return {"username": "current_user"}
316
317
def admin_required(current_user: dict = Depends(get_current_user)):
318
if not current_user.get("is_admin"):
319
raise HTTPException(status_code=403, detail="Admin access required")
320
return current_user
321
322
# Router with shared dependencies
323
admin_router = APIRouter(
324
prefix="/admin",
325
tags=["admin"],
326
dependencies=[Depends(admin_required)]
327
)
328
329
@admin_router.get("/users")
330
def list_all_users():
331
return {"users": ["admin", "user1", "user2"]}
332
333
@admin_router.delete("/users/{user_id}")
334
def delete_user(user_id: int):
335
return {"message": f"User {user_id} deleted"}
336
```
337
338
### Nested Routers
339
340
```python
341
from fastapi import APIRouter, FastAPI
342
343
# Create nested router structure
344
api_v1_router = APIRouter(prefix="/api/v1")
345
346
users_router = APIRouter(prefix="/users", tags=["users"])
347
posts_router = APIRouter(prefix="/posts", tags=["posts"])
348
349
@users_router.get("/")
350
def get_users():
351
return {"users": []}
352
353
@posts_router.get("/")
354
def get_posts():
355
return {"posts": []}
356
357
# Include sub-routers in API v1 router
358
api_v1_router.include_router(users_router)
359
api_v1_router.include_router(posts_router)
360
361
# Include API v1 router in main application
362
app = FastAPI()
363
app.include_router(api_v1_router)
364
365
# This creates endpoints:
366
# GET /api/v1/users/
367
# GET /api/v1/posts/
368
```
369
370
### Router with Custom Response Models
371
372
```python
373
from fastapi import APIRouter
374
from pydantic import BaseModel
375
from typing import List
376
377
class User(BaseModel):
378
id: int
379
username: str
380
email: str
381
382
class UserCreate(BaseModel):
383
username: str
384
email: str
385
386
# Router with default response class
387
users_router = APIRouter(
388
prefix="/users",
389
tags=["users"],
390
responses={
391
404: {"description": "User not found"},
392
422: {"description": "Validation error"}
393
}
394
)
395
396
@users_router.get("/", response_model=List[User])
397
def get_users():
398
return [
399
{"id": 1, "username": "john", "email": "john@example.com"},
400
{"id": 2, "username": "jane", "email": "jane@example.com"}
401
]
402
403
@users_router.post("/", response_model=User, status_code=201)
404
def create_user(user: UserCreate):
405
return {"id": 3, **user.dict()}
406
```