Skip to main content
Middleware allows you to run code before and after each request. FastrAPI provides built-in middleware for common tasks like CORS, compression, sessions, and trusted host validation, plus support for custom middleware.

Built-in middleware

FastrAPI includes four production-ready middleware implementations powered by Rust for optimal performance:

CORS

Cross-Origin Resource Sharing configuration

GZip

Response compression

Sessions

Cookie-based session management

TrustedHost

Host header validation

Adding middleware

Use the add_middleware() method to add middleware to your application. Middleware is executed in the order it’s added.
from fastrapi import FastrAPI
from fastrapi.middleware import CORSMiddleware

app = FastrAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["GET", "POST"],
    allow_headers=["*"]
)
Middleware is processed in the order it’s added. The first middleware added wraps all subsequent middleware and routes.

CORS middleware

Configure Cross-Origin Resource Sharing (CORS) to control which domains can access your API.
from fastrapi import FastrAPI
from fastrapi.responses import JSONResponse
from fastrapi.middleware import CORSMiddleware

app = FastrAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["GET", "POST"],
    allow_headers=["*"],
    allow_credentials=False
)

@app.get("/")
def index() -> JSONResponse:
    return JSONResponse({"status": "running"})

if __name__ == "__main__":
    app.serve("127.0.0.1", 8000)

CORS configuration options

allow_origins
list[str]
default:"[]"
List of origins that are allowed to make cross-origin requests. Use ["*"] to allow all origins.
allow_methods
list[str]
default:"['GET', 'POST', 'PUT', 'DELETE']"
HTTP methods that are allowed for cross-origin requests. Use ["*"] to allow all methods.
allow_headers
list[str]
default:"[]"
HTTP headers that are allowed in cross-origin requests. Use ["*"] to allow all headers.
allow_credentials
bool
default:"false"
Whether to allow cookies and authentication headers in cross-origin requests.
expose_headers
list[str]
default:"[]"
Headers that are exposed to the browser in the response.
max_age
int
default:"600"
Maximum number of seconds the browser can cache the CORS preflight response.
Be careful with allow_origins=["*"] and allow_credentials=True together. For security reasons, browsers don’t allow this combination. If you need credentials, specify exact origins.

GZip middleware

Compress responses with GZip to reduce bandwidth usage and improve load times.
from fastrapi import FastrAPI
from fastrapi.responses import JSONResponse
from fastrapi.middleware import GZipMiddleware

app = FastrAPI()

app.add_middleware(
    GZipMiddleware,
    minimum_size=500,
    compresslevel=9
)

@app.get("/heavy")
def heavy_data() -> JSONResponse:
    # Response large enough to trigger GZip compression
    large_data = "x" * 1000
    return JSONResponse({
        "data": large_data,
        "note": "Check content-encoding header!"
    })

GZip configuration options

minimum_size
int
default:"500"
Minimum response size in bytes to trigger compression. Responses smaller than this won’t be compressed.
compresslevel
int
default:"9"
Compression level from 1 (fastest) to 9 (best compression). Higher levels use more CPU but produce smaller responses.
The compression happens at the Rust layer for maximum performance with minimal overhead.

Session middleware

Manage user sessions with secure, signed cookies.
from fastrapi import FastrAPI
from fastrapi.responses import JSONResponse
from fastrapi.middleware import SessionMiddleware

app = FastrAPI()

app.add_middleware(
    SessionMiddleware,
    secret_key="your-secret-key-change-this-in-production",
    session_cookie="fastrapi_session",
    max_age=3600,
    https_only=False
)

@app.get("/counter")
def session_counter(request) -> JSONResponse:
    return JSONResponse({"message": "Session cookie should be set"})

if __name__ == "__main__":
    app.serve("127.0.0.1", 8000)

Session configuration options

secret_key
str
required
Secret key used to sign session cookies. Must be long and random. Never commit this to version control.
Name of the session cookie.
max_age
int
default:"1209600"
Session lifetime in seconds. Default is 14 days (1209600 seconds).
path
str
default:"'/'"
Cookie path. Use / to make the session available across your entire application.
same_site
str
default:"'lax'"
SameSite cookie attribute. Options: 'strict', 'lax', or 'none'.
https_only
bool
default:"false"
Whether to only send cookies over HTTPS. Set to true in production.
domain
str
default:"None"
Cookie domain. Set this to share sessions across subdomains.
Security considerations:
  • Use a strong, randomly generated secret_key
  • Set https_only=True in production
  • Use environment variables for the secret key
  • Rotate keys periodically

TrustedHost middleware

Validate the Host header to prevent host header injection attacks.
from fastrapi import FastrAPI
from fastrapi.middleware import TrustedHostMiddleware

app = FastrAPI()

app.add_middleware(
    TrustedHostMiddleware,
    allowed_hosts=["127.0.0.1", "localhost", "127.0.0.1:8000"],
    www_redirect=True
)

if __name__ == "__main__":
    app.serve("127.0.0.1", 8000)

TrustedHost configuration options

allowed_hosts
list[str]
default:"['*']"
List of allowed host values. Use ["*"] to allow all hosts (not recommended in production).
www_redirect
bool
default:"true"
Whether to redirect example.com to www.example.com.

Combining multiple middleware

You can stack multiple middleware layers. They’re executed in the order added:
from fastrapi import FastrAPI
from fastrapi.responses import JSONResponse
from fastrapi.middleware import (
    CORSMiddleware,
    TrustedHostMiddleware,
    GZipMiddleware,
    SessionMiddleware
)

app = FastrAPI()

# 1. TrustedHost - validate host first
app.add_middleware(
    TrustedHostMiddleware,
    allowed_hosts=["127.0.0.1", "localhost", "127.0.0.1:8000"],
    www_redirect=True
)

# 2. CORS - handle cross-origin requests
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_methods=["GET", "POST"],
    allow_headers=["*"],
    allow_credentials=False
)

# 3. GZip - compress responses
app.add_middleware(
    GZipMiddleware,
    minimum_size=500,
    compresslevel=9
)

# 4. Session - manage user sessions
app.add_middleware(
    SessionMiddleware,
    secret_key="super-secret-key-change-in-production",
    session_cookie="fastrapi_session",
    max_age=3600,
    https_only=False
)

@app.get("/")
def index() -> JSONResponse:
    return JSONResponse({"status": "running"})

@app.get("/heavy")
def heavy_data() -> JSONResponse:
    large_data = "x" * 1000
    return JSONResponse({
        "data": large_data,
        "note": "Check content-encoding header!"
    })

if __name__ == "__main__":
    app.serve("127.0.0.1", 8000)
Middleware execution order:
  1. TrustedHost validates the host header
  2. CORS handles preflight and adds headers
  3. Your route handler executes
  4. GZip compresses the response
  5. Session sets/reads cookies

Custom middleware

You can create custom middleware using Python functions:
from fastrapi import FastrAPI

app = FastrAPI()

def auth_middleware(request):
    # Access request information
    if request.get("path") == "/admin" and "Authorization" not in request.get("headers", {}):
        return {"error": "Unauthorized"}, 401
    # Return None to continue to the route handler
    return None

app.add_middleware(auth_middleware)

@app.get("/admin")
def admin_panel():
    return {"message": "Admin access granted"}
Custom middleware functions receive a request dictionary with method, path, query, and headers keys. Return None to continue processing, or return a response to short-circuit.

Performance

All built-in middleware is implemented in Rust and integrated with Axum’s Tower middleware system, providing:
  • Zero-copy operations where possible
  • Minimal allocations
  • Native async/await support
  • Efficient header manipulation
This architecture means middleware overhead is measured in microseconds rather than milliseconds.

Best practices

Add middleware in order of importance. Security middleware (TrustedHost) should come first, followed by CORS, then compression and sessions.
Never hardcode secret keys. Use environment variables:
import os

app.add_middleware(
    SessionMiddleware,
    secret_key=os.environ["SESSION_SECRET"]
)
Always set https_only=True for SessionMiddleware in production environments.
Balance compression level with CPU usage. Level 6 is often a good compromise:
app.add_middleware(
    GZipMiddleware,
    compresslevel=6  # Good balance
)

Request handling

Understand request processing

Background tasks

Execute tasks asynchronously

API reference

Middleware API documentation

Error handling

Handle middleware errors

Build docs developers (and LLMs) love