Skip to main content

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 sent
  • Content-Length: Indicates the size of the response body
  • Access-Control-Allow-Origin: Controls cross-origin resource sharing (CORS)
  • Cache-Control: Defines caching policies
  • Set-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:

python
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:

python
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:

python
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:

python
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:

python
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:

python
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:

python
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:

python
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:

python
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:

python
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

Exercises

  1. Create an API endpoint that returns a JSON response with a custom header indicating the time the response was generated.
  2. Implement a middleware that adds security headers to all responses in your application.
  3. Build an API that serves different data formats based on an Accept header, and sets appropriate Content-Type headers in the response.
  4. Create an endpoint that simulates a file download with proper Content-Disposition and Content-Length headers.


If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)