FastAPI Deep Tech Intuition
A senior-engineer-level guide to FastAPI — not just syntax, but the mental models, design decisions, and production patterns.
FastAPI in one sentence
FastAPI is Pydantic for I/O validation + Starlette for ASGI + a dependency injection system — wrapped in a thin layer that turns Python type hints into a runtime contract.
Once you see the three pieces independently, the framework stops feeling magical.
The three layers
1. Starlette: the transport layer
ASGI is the async successor to WSGI. Starlette gives you routing, middleware, websockets, and request/response objects on top of it. FastAPI inherits all of it — app.add_middleware(...) is Starlette.
2. Pydantic: the data layer
Every request body, query parameter, and response model passes through Pydantic. Validation, coercion, and JSON-schema generation come from one source of truth: your type annotations.
from pydantic import BaseModel
class User(BaseModel):
id: int
email: str
is_active: bool = True
3. Dependency injection: the wiring layer
The thing that confuses newcomers most. Depends(get_db) is not magic — it’s a callable resolver, cached per-request, that gets evaluated before your handler runs.
from fastapi import Depends, FastAPI
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/users/{id}")
def read_user(id: int, db = Depends(get_db)):
return db.query(User).get(id)
Production patterns
- Always pin response models.
response_model=UserPublicstrips internal fields and locks the API contract. - Move heavy work to background tasks or a real queue —
BackgroundTasksis fine for fire-and-forget, but use Celery/RQ/arq for anything that must survive a restart. - Use lifespan events for startup/shutdown resource management. The old
@app.on_event("startup")is deprecated.
Where it falls short
FastAPI is excellent for typed JSON APIs. It is not what you want for server-rendered HTML at scale, long-lived stateful connections, or anything where you need fine-grained control over the ASGI cycle.