Middleware
Learn how to use middleware in the Instructor HTTP client API.
Middleware is one of the most powerful features of the Instructor HTTP client API. It allows you to intercept and modify HTTP requests and responses, add functionality to the HTTP client, and create reusable components that can be applied across different applications.
Middleware Concept
Middleware in the Instructor HTTP client API follows the pipeline pattern, where each middleware component gets a chance to process the request before it’s sent and the response after it’s received.
The middleware chain works like this:
- Your application creates a request
- The request passes through each middleware (in the order they were added)
- The last middleware passes the request to the HTTP driver
- The driver sends the request to the server and receives a response
- The response passes back through each middleware (in reverse order)
- Your application receives the final response
This bidirectional flow allows middleware to perform operations both before the request is sent and after the response is received.
The HttpMiddleware Interface
All middleware components must implement the HttpMiddleware
interface:
The handle
method takes two parameters:
$request
: The HTTP request to process$next
: The next handler in the middleware chain
The middleware can:
- Modify the request before passing it to the next handler
- Short-circuit the chain by returning a response without calling the next handler
- Process the response from the next handler before returning it
- Wrap the response in a decorator for further processing (especially useful for streaming responses)
The BaseMiddleware Abstract Class
While you can implement the HttpMiddleware
interface directly, the library provides a convenient BaseMiddleware
abstract class that makes it easier to create middleware:
By extending BaseMiddleware
, you only need to override the methods relevant to your middleware’s functionality, making the code more focused and maintainable.
Middleware Stack
The MiddlewareStack
class manages the collection of middleware components. It provides methods to add, remove, and arrange middleware in the stack.
Adding Middleware
There are several ways to add middleware to the stack:
Named middleware are useful when you need to reference them later, for example, to remove or replace them.
Removing Middleware
You can remove middleware from the stack by name:
Replacing Middleware
You can replace a middleware with another one:
Clearing Middleware
You can remove all middleware from the stack:
Checking Middleware
You can check if a middleware exists in the stack:
Getting Middleware
You can get a middleware from the stack by name or index:
Middleware Order
The order of middleware in the stack is important because:
- Requests pass through middleware in the order they were added to the stack
- Responses pass through middleware in reverse order
For example, if you add middleware in this order:
- Authentication middleware
- Logging middleware
- Retry middleware
The execution flow will be:
- Request: Authentication → Logging → Retry → HTTP Driver
- Response: Retry → Logging → Authentication → Your Application
This allows you to nest functionality appropriately. For instance, the authentication middleware might add headers to the request and then verify the authentication status of the response before your application receives it.
Middleware Application Example
Here’s an example of how middleware is applied in a request-response cycle:
Built-in Middleware
The Instructor HTTP client API includes several built-in middleware components for common tasks:
Debug Middleware
The DebugMiddleware
logs detailed information about HTTP requests and responses:
The debug middleware logs:
- Request URLs
- Request headers
- Request bodies
- Response headers
- Response bodies
- Streaming response data
You can configure which aspects to log in the config/debug.php
file:
BufferResponse Middleware
The BufferResponseMiddleware
stores response bodies and streaming chunks for reuse:
This middleware is useful when you need to access a response body or stream multiple times, as it stores the data after the first access.
StreamByLine Middleware
The StreamByLineMiddleware
processes streaming responses line by line:
You can customize how lines are processed by providing a parser function:
RecordReplay Middleware
The RecordReplayMiddleware
records HTTP interactions and can replay them later:
The middleware has three modes:
MODE_PASS
: Normal operation, no recording or replayingMODE_RECORD
: Records all HTTP interactions to the storage directoryMODE_REPLAY
: Replays recorded interactions instead of making real requests
This is particularly useful for:
- Testing: Record real API responses once, then replay them in tests
- Offline development: Develop without access to real APIs
- Demo environments: Ensure consistent responses for demos
- Performance testing: Replay recorded responses to eliminate API variability
Example of switching modes:
Example Middleware Combinations
Here are some common middleware combinations for different scenarios:
Debugging Setup
API Client Setup
Testing Setup
Streaming Setup
By combining middleware components, you can create a highly customized HTTP client that handles complex requirements while keeping your application code clean and focused.
In the next chapter, we’ll explore how to create custom middleware components to handle specific requirements.