or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

api-routing.mdbackground-tasks.mdcore-application.mddependency-injection.mdexception-handling.mdfile-handling.mdindex.mdparameter-declaration.mdrequest-response.mdwebsocket-support.md

api-routing.mddocs/

0

# API Routing

1

2

The APIRouter class enables modular organization of API endpoints into logical groups with shared configuration like prefixes, tags, dependencies, and responses. Routers can be nested hierarchically and included in the main FastAPI application or other routers.

3

4

## Capabilities

5

6

### APIRouter Class

7

8

Router class for grouping related endpoints with shared configuration and hierarchical organization.

9

10

```python { .api }

11

class APIRouter:

12

def __init__(

13

self,

14

*,

15

prefix: str = "",

16

tags: Optional[List[Union[str, Enum]]] = None,

17

dependencies: Optional[Sequence[Depends]] = None,

18

default_response_class: Type[Response] = Default(JSONResponse),

19

responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,

20

callbacks: Optional[List[BaseRoute]] = None,

21

routes: Optional[List[BaseRoute]] = None,

22

redirect_slashes: bool = True,

23

default: Optional[ASGIApp] = None,

24

dependency_overrides_provider: Optional[Any] = None,

25

route_class: Type[APIRoute] = APIRoute,

26

on_startup: Optional[Sequence[Callable]] = None,

27

on_shutdown: Optional[Sequence[Callable]] = None,

28

lifespan: Optional[Callable] = None,

29

deprecated: Optional[bool] = None,

30

include_in_schema: bool = True,

31

generate_unique_id_function: Callable[[APIRoute], str] = Default(generate_unique_id)

32

):

33

"""

34

Create an APIRouter instance.

35

36

Parameters:

37

- prefix: URL prefix for all routes in this router

38

- tags: List of tags applied to all routes in this router

39

- dependencies: List of dependencies applied to all routes in this router

40

- default_response_class: Default response class for all routes

41

- responses: Default additional responses for all routes

42

- callbacks: List of callback routes

43

- routes: List of route instances to include

44

- redirect_slashes: Automatically redirect URLs with trailing slashes

45

- default: Default ASGI app to call for unmatched routes

46

- dependency_overrides_provider: Provider for dependency overrides

47

- route_class: Class to use for API routes

48

- on_startup: Functions to run on router startup (deprecated)

49

- on_shutdown: Functions to run on router shutdown (deprecated)

50

- lifespan: Async context manager for router lifespan events

51

- deprecated: Mark all routes in this router as deprecated

52

- include_in_schema: Include all routes in OpenAPI schema

53

- generate_unique_id_function: Function to generate unique operation IDs

54

"""

55

```

56

57

### HTTP Method Decorators

58

59

Decorators for defining HTTP endpoints within the router with the same functionality as FastAPI application decorators.

60

61

```python { .api }

62

def get(

63

self,

64

path: str,

65

*,

66

response_model: Any = Default(None),

67

status_code: Optional[int] = None,

68

tags: Optional[List[Union[str, Enum]]] = None,

69

dependencies: Optional[Sequence[Depends]] = None,

70

summary: Optional[str] = None,

71

description: Optional[str] = None,

72

response_description: str = "Successful Response",

73

responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,

74

deprecated: Optional[bool] = None,

75

operation_id: Optional[str] = None,

76

response_model_include: Optional[IncEx] = None,

77

response_model_exclude: Optional[IncEx] = None,

78

response_model_by_alias: bool = True,

79

response_model_exclude_unset: bool = False,

80

response_model_exclude_defaults: bool = False,

81

response_model_exclude_none: bool = False,

82

include_in_schema: bool = True,

83

response_class: Type[Response] = Default(JSONResponse),

84

name: Optional[str] = None,

85

callbacks: Optional[List[BaseRoute]] = None,

86

openapi_extra: Optional[Dict[str, Any]] = None,

87

generate_unique_id_function: Callable[[APIRoute], str] = Default(generate_unique_id)

88

) -> Callable[[DecoratedCallable], DecoratedCallable]:

89

"""Create a GET endpoint decorator within this router."""

90

91

def post(self, path: str, **kwargs) -> Callable:

92

"""Create a POST endpoint decorator within this router."""

93

94

def put(self, path: str, **kwargs) -> Callable:

95

"""Create a PUT endpoint decorator within this router."""

96

97

def delete(self, path: str, **kwargs) -> Callable:

98

"""Create a DELETE endpoint decorator within this router."""

99

100

def patch(self, path: str, **kwargs) -> Callable:

101

"""Create a PATCH endpoint decorator within this router."""

102

103

def options(self, path: str, **kwargs) -> Callable:

104

"""Create an OPTIONS endpoint decorator within this router."""

105

106

def head(self, path: str, **kwargs) -> Callable:

107

"""Create a HEAD endpoint decorator within this router."""

108

109

def trace(self, path: str, **kwargs) -> Callable:

110

"""Create a TRACE endpoint decorator within this router."""

111

```

112

113

### WebSocket Support

114

115

Decorator for defining WebSocket endpoints within the router.

116

117

```python { .api }

118

def websocket(

119

self,

120

path: str,

121

*,

122

name: Optional[str] = None,

123

dependencies: Optional[Sequence[Depends]] = None,

124

) -> Callable[[DecoratedCallable], DecoratedCallable]:

125

"""

126

Create a WebSocket endpoint decorator within this router.

127

128

Parameters:

129

- path: URL path for the WebSocket endpoint

130

- name: Name for the endpoint (for URL reversing)

131

- dependencies: List of dependencies for this endpoint

132

"""

133

```

134

135

### Router Inclusion

136

137

Method for including other routers within this router, enabling hierarchical router organization.

138

139

```python { .api }

140

def include_router(

141

self,

142

router: "APIRouter",

143

*,

144

prefix: str = "",

145

tags: Optional[List[Union[str, Enum]]] = None,

146

dependencies: Optional[Sequence[Depends]] = None,

147

responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,

148

deprecated: Optional[bool] = None,

149

include_in_schema: bool = True,

150

default_response_class: Type[Response] = Default(JSONResponse),

151

callbacks: Optional[List[BaseRoute]] = None

152

) -> None:

153

"""

154

Include another APIRouter within this router.

155

156

Parameters:

157

- router: APIRouter instance to include

158

- prefix: Additional URL prefix for the included router

159

- tags: Additional tags for all routes in the included router

160

- dependencies: Additional dependencies for all routes in the included router

161

- responses: Additional responses for all routes in the included router

162

- deprecated: Mark all routes in the included router as deprecated

163

- include_in_schema: Include included router routes in OpenAPI schema

164

- default_response_class: Default response class for included router routes

165

- callbacks: Additional callbacks for all routes in the included router

166

"""

167

```

168

169

### Programmatic Route Management

170

171

Methods for adding routes programmatically instead of using decorators.

172

173

```python { .api }

174

def add_api_route(

175

self,

176

path: str,

177

endpoint: Callable,

178

*,

179

methods: Optional[Union[Set[str], List[str]]] = None,

180

name: Optional[str] = None,

181

dependencies: Optional[Sequence[Depends]] = None,

182

**kwargs: Any

183

) -> None:

184

"""

185

Add an API route programmatically to this router.

186

187

Parameters:

188

- path: URL path for the route

189

- endpoint: Function to handle the route

190

- methods: HTTP methods for the route (defaults to ["GET"])

191

- name: Name for the route

192

- dependencies: Dependencies for the route

193

"""

194

195

def add_websocket_route(

196

self,

197

path: str,

198

endpoint: Callable,

199

name: Optional[str] = None

200

) -> None:

201

"""

202

Add a WebSocket route programmatically to this router.

203

204

Parameters:

205

- path: URL path for the WebSocket route

206

- endpoint: Function to handle the WebSocket connection

207

- name: Name for the route

208

"""

209

```

210

211

### Generic Route Decorator

212

213

Generic decorator for creating routes with custom HTTP methods.

214

215

```python { .api }

216

def route(

217

self,

218

path: str,

219

methods: Optional[List[str]] = None,

220

name: Optional[str] = None,

221

include_in_schema: bool = True

222

) -> Callable:

223

"""

224

Create a generic route decorator for custom HTTP methods.

225

226

Parameters:

227

- path: URL path for the route

228

- methods: List of HTTP methods to handle

229

- name: Name for the route

230

- include_in_schema: Include route in OpenAPI schema

231

"""

232

```

233

234

### Sub-Application Mounting

235

236

Method for mounting WSGI or ASGI applications within the router.

237

238

```python { .api }

239

def mount(

240

self,

241

path: str,

242

app: ASGIApp,

243

name: Optional[str] = None

244

) -> None:

245

"""

246

Mount a sub-application at the given path within this router.

247

248

Parameters:

249

- path: Path to mount the application at

250

- app: WSGI or ASGI application to mount

251

- name: Name for the mounted application

252

"""

253

```

254

255

## Route Classes

256

257

### APIRoute

258

259

Class representing individual API routes with their configuration and metadata.

260

261

```python { .api }

262

class APIRoute:

263

def __init__(

264

self,

265

path: str,

266

endpoint: Callable,

267

*,

268

response_model: Any = Default(None),

269

status_code: Optional[int] = None,

270

tags: Optional[List[Union[str, Enum]]] = None,

271

dependencies: Optional[Sequence[Depends]] = None,

272

summary: Optional[str] = None,

273

description: Optional[str] = None,

274

response_description: str = "Successful Response",

275

responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,

276

deprecated: Optional[bool] = None,

277

methods: Optional[Union[Set[str], List[str]]] = None,

278

operation_id: Optional[str] = None,

279

response_model_include: Optional[IncEx] = None,

280

response_model_exclude: Optional[IncEx] = None,

281

response_model_by_alias: bool = True,

282

response_model_exclude_unset: bool = False,

283

response_model_exclude_defaults: bool = False,

284

response_model_exclude_none: bool = False,

285

include_in_schema: bool = True,

286

response_class: Type[Response] = Default(JSONResponse),

287

name: Optional[str] = None,

288

callbacks: Optional[List[BaseRoute]] = None,

289

openapi_extra: Optional[Dict[str, Any]] = None,

290

generate_unique_id_function: Callable[["APIRoute"], str] = Default(generate_unique_id)

291

):

292

"""

293

Individual API route configuration.

294

295

Properties:

296

- path: URL path pattern

297

- endpoint: Handler function

298

- methods: HTTP methods handled by this route

299

- response_model: Pydantic model for response serialization

300

- status_code: Default HTTP status code

301

- tags: OpenAPI tags

302

- dependencies: Route-specific dependencies

303

- name: Route name for URL reversing

304

"""

305

```

306

307

### APIWebSocketRoute

308

309

Class representing WebSocket routes.

310

311

```python { .api }

312

class APIWebSocketRoute:

313

def __init__(

314

self,

315

path: str,

316

endpoint: Callable,

317

*,

318

name: Optional[str] = None,

319

dependencies: Optional[Sequence[Depends]] = None

320

):

321

"""

322

WebSocket route configuration.

323

324

Properties:

325

- path: URL path pattern

326

- endpoint: WebSocket handler function

327

- name: Route name for URL reversing

328

- dependencies: Route-specific dependencies

329

"""

330

```

331

332

## Usage Examples

333

334

### Basic Router Setup

335

336

```python

337

from fastapi import APIRouter, Depends

338

from pydantic import BaseModel

339

340

# Create router with shared configuration

341

router = APIRouter(

342

prefix="/items",

343

tags=["items"],

344

dependencies=[Depends(verify_auth)],

345

responses={404: {"description": "Not found"}}

346

)

347

348

class Item(BaseModel):

349

name: str

350

price: float

351

352

@router.get("/")

353

async def get_items():

354

return [{"name": "Item 1", "price": 10.5}]

355

356

@router.post("/", response_model=Item)

357

async def create_item(item: Item):

358

return item

359

360

@router.get("/{item_id}")

361

async def get_item(item_id: int):

362

return {"name": f"Item {item_id}", "price": 10.5}

363

```

364

365

### Hierarchical Router Organization

366

367

```python

368

from fastapi import FastAPI, APIRouter

369

370

# Main application

371

app = FastAPI()

372

373

# API v1 router

374

api_v1 = APIRouter(prefix="/api/v1")

375

376

# Feature-specific routers

377

users_router = APIRouter(prefix="/users", tags=["users"])

378

items_router = APIRouter(prefix="/items", tags=["items"])

379

380

@users_router.get("/")

381

async def get_users():

382

return [{"id": 1, "name": "John"}]

383

384

@users_router.get("/{user_id}")

385

async def get_user(user_id: int):

386

return {"id": user_id, "name": "John"}

387

388

@items_router.get("/")

389

async def get_items():

390

return [{"id": 1, "name": "Item 1"}]

391

392

# Include feature routers in API v1

393

api_v1.include_router(users_router)

394

api_v1.include_router(items_router)

395

396

# Include API v1 in main app

397

app.include_router(api_v1)

398

399

# Final URLs:

400

# GET /api/v1/users/

401

# GET /api/v1/users/{user_id}

402

# GET /api/v1/items/

403

```

404

405

### Router with Shared Dependencies

406

407

```python

408

from fastapi import APIRouter, Depends, HTTPException

409

410

def get_current_user(token: str = Depends(get_token)):

411

if not token:

412

raise HTTPException(status_code=401, detail="Not authenticated")

413

return {"user_id": 1, "username": "john"}

414

415

def verify_admin(user: dict = Depends(get_current_user)):

416

if not user.get("is_admin"):

417

raise HTTPException(status_code=403, detail="Not enough permissions")

418

return user

419

420

# Admin router with shared admin dependency

421

admin_router = APIRouter(

422

prefix="/admin",

423

tags=["admin"],

424

dependencies=[Depends(verify_admin)]

425

)

426

427

@admin_router.get("/users")

428

async def get_all_users():

429

# Only accessible by admin users

430

return [{"id": 1, "name": "John"}, {"id": 2, "name": "Jane"}]

431

432

@admin_router.delete("/users/{user_id}")

433

async def delete_user(user_id: int):

434

# Only accessible by admin users

435

return {"message": f"User {user_id} deleted"}

436

```

437

438

### Router with Custom Response Classes

439

440

```python

441

from fastapi import APIRouter

442

from fastapi.responses import PlainTextResponse, HTMLResponse

443

444

router = APIRouter(prefix="/content")

445

446

@router.get("/text", response_class=PlainTextResponse)

447

async def get_text():

448

return "This is plain text"

449

450

@router.get("/html", response_class=HTMLResponse)

451

async def get_html():

452

return "<html><body><h1>Hello HTML</h1></body></html>"

453

454

@router.get("/json") # Uses default JSONResponse

455

async def get_json():

456

return {"message": "This is JSON"}

457

```

458

459

### WebSocket Router

460

461

```python

462

from fastapi import APIRouter, WebSocket

463

464

ws_router = APIRouter(prefix="/ws")

465

466

@ws_router.websocket("/chat")

467

async def websocket_endpoint(websocket: WebSocket):

468

await websocket.accept()

469

try:

470

while True:

471

data = await websocket.receive_text()

472

await websocket.send_text(f"Message text was: {data}")

473

except WebSocketDisconnect:

474

print("Client disconnected")

475

```