FastAPI Response Headers
HTTP response headers are key-value pairs sent by the server in its response to a client's request. These headers contain metadata about the response, such as content type, cache controls, or custom application-specific information. In FastAPI, you have several ways to work with response headers to enhance your API's functionality and security.
Understanding Response Headers
Response headers provide crucial information to clients about how to handle the received data. Common HTTP headers include:
Content-Type
: Tells the client what kind of data is being sentContent-Length
: Indicates the size of the response bodyAccess-Control-Allow-Origin
: Controls cross-origin resource sharing (CORS)Cache-Control
: Defines caching policiesSet-Cookie
: Sets cookies in the client's browser
FastAPI provides multiple approaches for setting and managing these headers in your API responses.
Setting Response Headers in FastAPI
Method 1: Using the Response
Parameter
The simplest way to set headers is by using the Response
parameter in your path operation function:
from fastapi import FastAPI, Response
app = FastAPI()
@app.get("/items/")
async def read_items(response: Response):
response.headers["X-Custom-Header"] = "Custom Value"
response.headers["Cache-Control"] = "max-age=3600"
return {"message": "This response has custom headers"}
This approach is useful when you need to modify headers for a specific endpoint without changing the actual response data.
Method 2: Using Response Objects
FastAPI provides various Response classes that allow you to customize every aspect of the HTTP response:
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
@app.get("/custom-headers/")
async def get_custom_headers():
content = {"message": "Hello World"}
headers = {
"X-Custom-Header": "Example Value",
"Access-Control-Allow-Origin": "*"
}
return JSONResponse(content=content, headers=headers)
This approach gives you full control over the response, including status code, content, and headers.
Method 3: Using response_model
with Headers
You can combine FastAPI's response_model
with custom headers:
from fastapi import FastAPI, Response
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: int, response: Response):
response.headers["X-Item-ID"] = str(item_id)
return {"name": "Example Item", "price": 9.99}
This preserves the benefits of response model validation while allowing you to set custom headers.
Headers in Dependency Injection
You can also set headers using FastAPI's dependency injection system:
from fastapi import Depends, FastAPI, Response
app = FastAPI()
async def add_security_headers(response: Response):
response.headers["X-Content-Type-Options"] = "nosniff"
response.headers["X-Frame-Options"] = "DENY"
response.headers["X-XSS-Protection"] = "1; mode=block"
@app.get("/secure-endpoint/", dependencies=[Depends(add_security_headers)])
async def secure_endpoint():
return {"message": "This endpoint has security headers"}
This approach is excellent for adding consistent headers across multiple endpoints.
Global Headers with Middleware
To add headers to all responses in your application, you can use middleware:
from fastapi import FastAPI
from starlette.middleware.base import BaseHTTPMiddleware
app = FastAPI()
class HeaderMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request, call_next):
response = await call_next(request)
response.headers["X-App-Version"] = "1.0.0"
response.headers["Server"] = "CustomServer"
return response
app.add_middleware(HeaderMiddleware)
@app.get("/")
async def root():
return {"message": "Hello World"}
All responses from this application will include the specified headers.
Common Use Cases for Response Headers
1. CORS Headers
Cross-Origin Resource Sharing (CORS) headers control which domains can access your API:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["https://example.com"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
2. Cache Control
Optimize performance by controlling how responses are cached:
from fastapi import FastAPI, Response
app = FastAPI()
@app.get("/static-data/")
async def get_static_data(response: Response):
response.headers["Cache-Control"] = "max-age=86400" # Cache for 24 hours
return {"data": "This data rarely changes"}
@app.get("/dynamic-data/")
async def get_dynamic_data(response: Response):
response.headers["Cache-Control"] = "no-store" # Never cache
return {"data": "Fresh data every time"}
3. Content Security Policy
Enhance security by defining which content sources are allowed:
from fastapi import FastAPI, Response
app = FastAPI()
@app.get("/secure-page/")
async def secure_page(response: Response):
response.headers["Content-Security-Policy"] = "default-src 'self'; script-src 'self'"
return {"message": "This page has a strict CSP"}
Real-World Example: API Versioning with Headers
Headers can be used to implement API versioning:
from fastapi import FastAPI, Header, HTTPException
app = FastAPI()
@app.get("/users/")
async def get_users(x_api_version: str = Header(None)):
if x_api_version == "1.0":
return [{"id": 1, "name": "Alice"}]
elif x_api_version == "2.0":
return [{"id": 1, "name": "Alice", "email": "[email protected]"}]
else:
raise HTTPException(status_code=400, detail="Invalid API version")
Clients can specify the API version using the X-API-Version
header.
Practical Example: File Download with Headers
When serving files for download, setting the right headers is crucial:
from fastapi import FastAPI
from fastapi.responses import FileResponse
app = FastAPI()
@app.get("/download/report/")
async def download_report():
file_path = "reports/monthly_summary.pdf"
filename = "Monthly_Report.pdf"
headers = {
"Content-Disposition": f"attachment; filename={filename}",
"X-Download-Type": "Monthly Report"
}
return FileResponse(
path=file_path,
headers=headers,
media_type="application/pdf"
)
The Content-Disposition
header tells browsers to treat the response as a file download.
Summary
Response headers in FastAPI offer powerful ways to control how your API communicates with clients. You can:
- Set custom headers for individual endpoints using the
Response
parameter - Use response objects like
JSONResponse
for complete control - Add headers through dependencies for reusable header logic
- Implement global headers using middleware
- Enhance security, performance, and functionality through specialized headers
By mastering response headers, you can build more robust, secure, and efficient APIs that communicate effectively with clients.
Additional Resources
- FastAPI Official Documentation on Response Headers
- MDN Web Docs: HTTP headers
- OWASP Secure Headers Project
Exercises
- Create an API endpoint that returns a JSON response with a custom header indicating the time the response was generated.
- Implement a middleware that adds security headers to all responses in your application.
- Build an API that serves different data formats based on an
Accept
header, and sets appropriateContent-Type
headers in the response. - Create an endpoint that simulates a file download with proper
Content-Disposition
andContent-Length
headers.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)