Search Topics

Search across all FastAPI topics

GitHub

Architecture

5 topics

Patterns for structuring and scaling your FastAPI application. Routers for organization, dependencies for shared logic, and middleware for cross-cutting concerns.

Tip

FastAPI's dependency injection system is one of its most powerful features. It lets you compose complex behaviors from simple, testable functions.

How a Request Flows Through Your App

Step 1: HTTP Request

A client sends an HTTP request to your FastAPI application.

Try It: Middleware Layer Peeler

These are the patterns that trip up developers most often. Switch between Wrong and Fixed to compare the code side by side.

1
Circular imports with routers
Importing the app instance inside router modules
Don't do this
routers/users.py
# routers/users.py
from main import app  # Circular!

@app.get("/users")
async def list_users():
    return []
Never import the app instance into router modules. Instead, create an APIRouter and include it in the main app. This avoids circular imports and keeps modules independent.
2
Not using Depends() for shared logic
Duplicating authentication checks across endpoints
Don't do this
main.py
@app.get("/items")
async def list_items(token: str):
    user = verify_token(token)
    if not user:
        raise HTTPException(401)
    return get_items(user)

@app.get("/orders")
async def list_orders(token: str):
    user = verify_token(token)  # Duplicated!
    if not user:
        raise HTTPException(401)
    return get_orders(user)
Use Depends() to extract shared logic into reusable dependencies. This keeps your endpoints focused on business logic and makes authentication, database sessions, and other cross-cutting concerns easy to manage.