How to use filters in GuzzleHttp in Laravel
As a software developer, you've likely encountered the need to interact with external APIs in your Laravel applications. One of the most popular HTTP client libraries for PHP is GuzzleHttp, which provides a powerful and flexible way to make HTTP requests and handle responses.
In this article, we'll explore how to effectively use filters in GuzzleHttp within your Laravel projects. Filters are a powerful feature in GuzzleHttp that allow you to customize the behavior of your HTTP requests and responses. We'll cover how to create and apply filters, as well as provide examples of common use cases.
What are Filters in GuzzleHttp?
Filters in GuzzleHttp are middleware-like functions that can be applied to both requests and responses. These filters allow you to modify the behavior of your HTTP transactions, such as logging request and response data, adding or removing headers, and even transforming the response body.
GuzzleHttp provides a set of built-in filters, but you can also create your own custom filters to suit your specific needs. Filters are typically registered with a GuzzleHttp client instance, and they are then executed in the order they were registered.
Applying Filters in Laravel
To use filters in your Laravel application, you'll first need to install the GuzzleHttp package. You can do this by running the following command in your terminal:
composer require guzzlehttp/guzzle
Once the package is installed, you can start using filters in your code. Here's an example of how to create and apply a simple filter to log the request and response data:
use GuzzleHttp\Client;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
// Create a new GuzzleHttp client
$client = new Client();
// Define a filter to log request and response data
$logFilter = function (callable $handler) {
return function (RequestInterface $request, array $options) use ($handler) {
// Log the request
$this->logger->info('Sending request', [
'method' => $request->getMethod(),
'uri' => (string) $request->getUri(),
'headers' => $request->getHeaders(),
'body' => (string) $request->getBody(),
]);
// Send the request and get the response
$response = $handler($request, $options);
// Log the response
$this->logger->info('Received response', [
'status' => $response->getStatusCode(),
'headers' => $response->getHeaders(),
'body' => (string) $response->getBody(),
]);
return $response;
};
};
// Register the filter with the client
$client->getConfig('handler')->push($logFilter, 'log_filter');
// Make a request using the client
$response = $client->get('https://api.example.com/data');
In this example, we create a new filter function that logs the request and response data. We then register the filter with the GuzzleHttp client using the push()
method, which adds the filter to the client's middleware stack.
When we make a request using the client, the $logFilter
function will be executed before and after the request is sent, logging the relevant data to the application's logger.
Transforming the Response
One common use case for filters in GuzzleHttp is to transform the response data. For example, you might want to automatically deserialize the response body into a Laravel collection, making it easier to work with the data in your application.
Here's an example of how you can create a filter to do this:
use GuzzleHttp\Client;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
// Create a new GuzzleHttp client
$client = new Client();
// Define a filter to deserialize the response body into a Laravel collection
$collectionFilter = function (callable $handler) {
return function (RequestInterface $request, array $options) use ($handler) {
// Send the request and get the response
$response = $handler($request, $options);
// Deserialize the response body into a Laravel collection
$collection = collect(json_decode($response->getBody(), true));
// Return the collection instead of the original response
return $response->withBody(
\GuzzleHttp\Psr7\stream_for($collection->toJson())
);
};
};
// Register the filter with the client
$client->getConfig('handler')->push($collectionFilter, 'collection_filter');
// Make a request using the client
$response = $client->get('https://api.example.com/data');
// The response will now be a Laravel collection
$data = $response->getData();
In this example, we define a $collectionFilter
function that intercepts the response, deserializes the response body into a Laravel collection, and then returns the collection as the new response body.
We then register the filter with the GuzzleHttp client, and when we make a request using the client, the response will be a Laravel collection that we can work with directly in our application.
Caching Responses
Another common use case for filters in GuzzleHttp is to cache responses. This can be particularly useful when working with APIs that have rate limits or when you need to reduce the number of requests made to an external service.
Here's an example of how you can create a filter to cache responses:
use GuzzleHttp\Client;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use Illuminate\Support\Facades\Cache;
// Create a new GuzzleHttp client
$client = new Client();
// Define a filter to cache responses
$cacheFilter = function (callable $handler) {
return function (RequestInterface $request, array $options) use ($handler) {
// Generate a cache key based on the request
$cacheKey = 'guzzle_' . md5($request->getMethod() . $request->getUri());
// Check if the response is cached
if ($cachedResponse = Cache::get($cacheKey)) {
return $cachedResponse;
}
// Send the request and get the response
$response = $handler($request, $options);
// Cache the response
Cache::put($cacheKey, $response, now()->addMinutes(5));
return $response;
};
};
// Register the filter with the client
$client->getConfig('handler')->push($cacheFilter, 'cache_filter');
// Make a request using the client
$response = $client->get('https://api.example.com/data');
// The response will be cached for 5 minutes
$data = $response->getData();
In this example, we define a $cacheFilter
function that generates a cache key based on the request method and URI. It then checks if the response is already cached, and if so, it returns the cached response. If the response is not cached, it sends the request, caches the response for 5 minutes, and then returns the response.
We then register the filter with the GuzzleHttp client, and when we make a request using the client, the response will be cached for 5 minutes, reducing the number of requests made to the external API.
Conclusion
Filters in GuzzleHttp are a powerful tool for customizing the behavior of your HTTP requests and responses. In this article, we've covered how to create and apply filters, as well as provided examples of common use cases such as logging, transforming the response, and caching responses.
By using filters in your Laravel applications, you can build more robust and efficient integrations with external APIs, improving the overall performance and reliability of your application. Remember, the possibilities are endless when it comes to creating custom filters to suit your specific needs.
If you're interested in learning more about how Flowpoint.ai can help you identify and fix technical issues that are impacting your website's conversion rates, be sure to check out Flowpoint.ai
Get a Free AI Website Audit
Automatically identify UX and content issues affecting your conversion rates with Flowpoint's comprehensive AI-driven website audit.