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": "alice@example.com"}]
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 feedback@compilenrun.com. I’d greatly appreciate your feedback! :)