Skip to main content
FastAPI allows you to override the logic used by the Request and APIRoute classes. This is particularly useful when you need to customize how requests are processed before they reach your path operations.
This is an advanced feature. If you’re just starting with FastAPI, consider using middleware or dependencies for most customization needs.

When to Use Custom Classes

Custom Request and Route classes are good alternatives to middleware when you need to:
  • Transform request bodies: Convert non-JSON formats (like MessagePack) to JSON
  • Decompress data: Handle gzip-compressed request bodies
  • Log requests: Automatically log all request bodies
  • Add request metadata: Inject custom attributes into request objects
  • Measure performance: Track request processing time
Custom classes give you fine-grained control over request handling at the route level, whereas middleware operates globally.

Custom Request Class

A custom Request class allows you to override how the request body is processed.

Example: Gzip Request Handling

Here’s how to create a custom request class that handles gzip-compressed bodies:
This custom request class:
  1. Checks the Content-Encoding header for gzip
  2. If present, decompresses the body before returning it
  3. Otherwise, returns the body unchanged
By checking for the encoding header first, the same route can handle both compressed and uncompressed requests.

Custom APIRoute Class

To use your custom request class, you need to create a custom APIRoute class that instantiates it.

Creating a Custom Route

Understanding the Components

Technical Details:
  • request.scope: A Python dict containing request metadata (part of ASGI spec)
  • request.receive: A function to receive the request body (part of ASGI spec)
  • These components are all you need to create a new Request instance

Using Custom Routes in Your Application

Once you’ve created your custom route class, you can use it in several ways.

Method 1: Application-Wide

Apply the custom route to all endpoints in your application:

Method 2: Router-Specific

Apply the custom route to specific routers:
Using router-specific custom routes gives you fine-grained control over which endpoints use the custom behavior.

Advanced Example: Request Timing

Here’s a more advanced example that adds response time tracking:
Now every response will include an X-Process-Time header showing how long the request took to process.

Accessing Request Body in Exception Handlers

Custom routes can also help with error handling by preserving access to the request body:
The request body can only be read once. If you need to access it multiple times, store it in a variable or use request.scope to cache it.

Real-World Example: MessagePack Support

Here’s a practical example that adds MessagePack support to FastAPI:

Custom Request Attributes

You can add custom attributes to your request class:
Storing custom data in request.scope ensures it’s available throughout the request lifecycle and to all middleware and dependencies.

Best Practices

When creating custom request and route classes:
  1. Keep it simple: Only override what you need
  2. Handle errors gracefully: Always have fallback behavior
  3. Consider performance: Avoid heavy processing in the request class
  4. Document behavior: Make it clear what your custom class does
  5. Test thoroughly: Test both normal and edge cases

Alternative Approaches

Before implementing custom classes, consider:
  • Middleware: For application-wide request/response processing
  • Dependencies: For injection and validation logic
  • Background tasks: For async logging and monitoring
  • Exception handlers: For custom error handling

Comparison: Custom Routes vs Middleware

Learn More

Custom request and route classes are part of FastAPI’s advanced features that leverage Starlette’s ASGI capabilities.