Last active
November 24, 2021 11:46
-
-
Save pecuchet/90a2246a0c381b9a9a82fbe452ab4301 to your computer and use it in GitHub Desktop.
Simple Laravel 5.5 + Guzzle 6 cache middleware. This is now a composer package: https://github.com/brightfish-be/caching-guzzle.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php namespace App\Clients\Middleware; | |
use GuzzleHttp\Psr7\Response; | |
use Psr\Http\Message\RequestInterface; | |
use Psr\Http\Message\ResponseInterface; | |
use GuzzleHttp\Promise\PromiseInterface; | |
use GuzzleHttp\Promise\FulfilledPromise; | |
use Illuminate\Contracts\Cache\Repository; | |
/** | |
* Cache HTTP responses | |
* | |
* @version 0.0.1 | |
* @author dotburo <hello@dotburo.org> | |
*/ | |
class GuzzleResponseCache | |
{ | |
/** | |
* Cache time to live | |
* | |
* @var int | |
*/ | |
private $ttl = 7 * 24 * 60; // one week | |
/** | |
* A laravel cache driver instance | |
* | |
* @var Repository | |
*/ | |
private $cache; | |
/** | |
* Cache the laravel cache driver instance | |
* | |
* @param Repository $cache | |
* @param null $ttl | |
*/ | |
public function __construct(Repository $cache, $ttl = null) | |
{ | |
$this->cache = $cache; | |
$this->ttl = $ttl ?? $this->ttl; | |
} | |
/** | |
* The middleware handler | |
* | |
* @param callable $handler | |
* @return callable | |
*/ | |
public function __invoke(callable $handler): callable | |
{ | |
return function (RequestInterface $request, array $options) use (&$handler) { | |
# both path and query string are needed to build unique cache keys, | |
# eg. a REST URL doesn't necessarily contain a query string | |
$path = $request->getUri()->getPath(); | |
$query = $request->getUri()->getQuery(); | |
$key = "$path?$query"; | |
# get from cache | |
$entry = $this->get($key); | |
if ($entry) { | |
if (app()->environment() !== 'production') { | |
$this->log($key); | |
} | |
return new FulfilledPromise( | |
new Response(200, [], $entry) | |
); | |
} | |
/** @var PromiseInterface $promise */ | |
$promise = $handler($request, $options); | |
return $promise->then( | |
function (ResponseInterface $response) use ($options, $key) { | |
# save to cache | |
$this->save($key, (string)$response->getBody()); | |
return $response; | |
} | |
); | |
}; | |
} | |
/** | |
* Try getting cached data from cache | |
* | |
* @param string $key | |
* @return mixed|null | |
*/ | |
private function get(string $key) | |
{ | |
try { | |
return $this->cache->get($key); | |
} catch (\Exception $ignore) { | |
return null; | |
} | |
} | |
/** | |
* Persist the data to cache | |
* | |
* @param string $key | |
* @param string $data | |
* @return bool | |
*/ | |
private function save(string $key, string $data): bool | |
{ | |
try { | |
return $this->cache->add($key, $data, $this->ttl); | |
} catch (\Exception $ignore) { | |
return false; | |
} | |
} | |
/** | |
* Dump cache key to log file | |
* | |
* @param string $msg | |
* @return void | |
*/ | |
private function log(string $msg): void | |
{ | |
logger('Retrieved from cache: ' . $msg); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment