FASTAPI / 3. RESPONSE MODELS & STATUS CODES
Response Models, Status Codes & Error Handling
Controlling exactly what goes out, raising meaningful errors
EXPLANATION
Response models define the shape of what your API returns. This is separate from your internal models — you may store a password hash internally but never want it in the response. response_model= on the decorator tells FastAPI to filter and validate the output through a Pydantic model. Even if your function returns extra fields, only what's in the response model gets serialized and sent. This prevents accidental data leaks. response_model_exclude_unset=True means fields that weren't set (kept as defaults) are excluded from the response — great for PATCH endpoints where you only want changed fields. Status codes — FastAPI defaults to 200. Override with status_code=: • 201 Created → POST that creates a resource • 204 No Content → DELETE with no body • 400 Bad Request → client sent invalid data • 401 Unauthorized → not authenticated • 403 Forbidden → authenticated but not allowed • 404 Not Found → resource doesn't exist • 422 Unprocessable Entity → FastAPI raises this automatically for invalid bodies • 500 Internal Server Error → something broke on the server HTTPException raises an HTTP error with a status code and detail message. You can also create custom exception handlers with @app.exception_handler() to intercept any exception type and return a structured JSON error. Union response types (response_model=UserCreate | Message) let one endpoint return different shapes depending on the situation.
ARCHITECTURE
Your function returns:
{
"id": 1,
"username": "kamran",
"email": "k@nii.ac.in",
"hashed_password": "$2b$...", ← sensitive!
"is_admin": true
}
↓ response_model=UserPublic filters it
Client receives:
{
"id": 1,
"username": "kamran",
"email": "k@nii.ac.in"
← hashed_password GONE
← is_admin GONE
}
ERROR FLOW:
raise HTTPException(status_code=404, detail="User not found")
↓ FastAPI catches it
HTTP 404
{ "detail": "User not found" }CODE