{"id":13579278,"url":"https://github.com/Kevinrob/guzzle-cache-middleware","last_synced_at":"2025-04-05T20:33:36.739Z","repository":{"id":33372597,"uuid":"37017492","full_name":"Kevinrob/guzzle-cache-middleware","owner":"Kevinrob","description":"A HTTP Cache for Guzzle 6. It's a simple Middleware to be added in the HandlerStack.","archived":false,"fork":false,"pushed_at":"2024-03-18T11:56:50.000Z","size":330,"stargazers_count":404,"open_issues_count":27,"forks_count":76,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-05-18T10:02:54.321Z","etag":null,"topics":["cache","doctrine","flysystem","guzzle","handlerstack","http","laravel-cache","middleware","performance","psr-16","psr-6","psr-7","rfc-7234"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kevinrob.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-06-07T13:25:41.000Z","updated_at":"2024-06-18T10:48:15.291Z","dependencies_parsed_at":"2023-02-14T18:05:27.411Z","dependency_job_id":"51fc9d2f-d2f6-4ba9-a9c8-6bd687a58182","html_url":"https://github.com/Kevinrob/guzzle-cache-middleware","commit_stats":{"total_commits":344,"total_committers":55,"mean_commits":6.254545454545455,"dds":"0.39534883720930236","last_synced_commit":"24b93edc942f2eaaeb17f7ae0d6db0f77f4ed4ea"},"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kevinrob%2Fguzzle-cache-middleware","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kevinrob%2Fguzzle-cache-middleware/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kevinrob%2Fguzzle-cache-middleware/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kevinrob%2Fguzzle-cache-middleware/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kevinrob","download_url":"https://codeload.github.com/Kevinrob/guzzle-cache-middleware/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247399874,"owners_count":20932876,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cache","doctrine","flysystem","guzzle","handlerstack","http","laravel-cache","middleware","performance","psr-16","psr-6","psr-7","rfc-7234"],"created_at":"2024-08-01T15:01:37.997Z","updated_at":"2025-04-05T20:33:31.727Z","avatar_url":"https://github.com/Kevinrob.png","language":"PHP","readme":"# guzzle-cache-middleware\n\n[![Latest Stable Version](https://poser.pugx.org/kevinrob/guzzle-cache-middleware/v/stable)](https://packagist.org/packages/kevinrob/guzzle-cache-middleware) [![Total Downloads](https://poser.pugx.org/kevinrob/guzzle-cache-middleware/downloads)](https://packagist.org/packages/kevinrob/guzzle-cache-middleware) [![License](https://poser.pugx.org/kevinrob/guzzle-cache-middleware/license)](https://packagist.org/packages/kevinrob/guzzle-cache-middleware)\n![Tests](https://github.com/Kevinrob/guzzle-cache-middleware/workflows/Tests/badge.svg) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/Kevinrob/guzzle-cache-middleware/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/Kevinrob/guzzle-cache-middleware/?branch=master) [![Code Coverage](https://scrutinizer-ci.com/g/Kevinrob/guzzle-cache-middleware/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/Kevinrob/guzzle-cache-middleware/?branch=master)\n\n\nA HTTP Cache for [Guzzle](https://github.com/guzzle/guzzle) 6+. It's a simple Middleware to be added in the HandlerStack.\n\n## Goals\n- RFC 7234 compliance\n- Performance and transparency\n- Assured compatibility with PSR-7\n\n## Built-in storage interfaces\n- [Doctrine cache](https://github.com/doctrine/cache)\n- [Laravel cache](https://laravel.com/docs/5.2/cache)\n- [Flysystem](https://github.com/thephpleague/flysystem)\n- [PSR6](https://github.com/php-fig/cache)\n- [WordPress Object Cache](https://codex.wordpress.org/Class_Reference/WP_Object_Cache)\n\n## Installation\n\n`composer require kevinrob/guzzle-cache-middleware`\n\nor add it the your `composer.json` and run `composer update kevinrob/guzzle-cache-middleware`.\n\n# Why?\nPerformance. It's very common to do some HTTP calls to an API for rendering a page and it takes times to do it.\n\n# How?\nWith a simple Middleware added at the top of the `HandlerStack` of Guzzle.\n\n```php\nuse GuzzleHttp\\Client;\nuse GuzzleHttp\\HandlerStack;\nuse Kevinrob\\GuzzleCache\\CacheMiddleware;\n\n// Create default HandlerStack\n$stack = HandlerStack::create();\n\n// Add this middleware to the top with `push`\n$stack-\u003epush(new CacheMiddleware(), 'cache');\n\n// Initialize the client with the handler option\n$client = new Client(['handler' =\u003e $stack]);\n```\n\n# Examples\n\n## Doctrine/Cache\nYou can use a cache from `Doctrine/Cache`:\n```php\n[...]\nuse Doctrine\\Common\\Cache\\FilesystemCache;\nuse Kevinrob\\GuzzleCache\\Strategy\\PrivateCacheStrategy;\nuse Kevinrob\\GuzzleCache\\Storage\\DoctrineCacheStorage;\n\n[...]\n$stack-\u003epush(\n  new CacheMiddleware(\n    new PrivateCacheStrategy(\n      new DoctrineCacheStorage(\n        new FilesystemCache('/tmp/')\n      )\n    )\n  ),\n  'cache'\n);\n```\n\nYou can use `ChainCache` for using multiple `CacheProvider` instances. With that provider, you have to sort the different caches from the faster to the slower. Like that, you can have a very fast cache.\n```php\n[...]\nuse Doctrine\\Common\\Cache\\ChainCache;\nuse Doctrine\\Common\\Cache\\ArrayCache;\nuse Doctrine\\Common\\Cache\\FilesystemCache;\nuse Kevinrob\\GuzzleCache\\Strategy\\PrivateCacheStrategy;\nuse Kevinrob\\GuzzleCache\\Storage\\DoctrineCacheStorage;\n\n[...]\n$stack-\u003epush(new CacheMiddleware(\n  new PrivateCacheStrategy(\n    new DoctrineCacheStorage(\n      new ChainCache([\n        new ArrayCache(),\n        new FilesystemCache('/tmp/'),\n      ])\n    )\n  )\n), 'cache');\n```\n\n## Laravel cache\nYou can use a cache with Laravel, e.g. Redis, Memcache etc.:\n```php\n[...]\nuse Illuminate\\Support\\Facades\\Cache;\nuse Kevinrob\\GuzzleCache\\Strategy\\PrivateCacheStrategy;\nuse Kevinrob\\GuzzleCache\\Storage\\LaravelCacheStorage;\n\n[...]\n\n$stack-\u003epush(\n  new CacheMiddleware(\n    new PrivateCacheStrategy(\n      new LaravelCacheStorage(\n        Cache::store('redis')\n      )\n    )\n  ),\n  'cache'\n);\n```\n\n## Flysystem\n```php\n[...]\nuse League\\Flysystem\\Adapter\\Local;\nuse Kevinrob\\GuzzleCache\\Strategy\\PrivateCacheStrategy;\nuse Kevinrob\\GuzzleCache\\Storage\\FlysystemStorage;\n\n[...]\n\n$stack-\u003epush(\n  new CacheMiddleware(\n    new PrivateCacheStrategy(\n      new FlysystemStorage(\n        new Local('/path/to/cache')\n      )\n    )\n  ),\n  'cache'\n);\n```\n\n## WordPress Object Cache\n```php\n[...]\nuse Kevinrob\\GuzzleCache\\Strategy\\PrivateCacheStrategy;\nuse Kevinrob\\GuzzleCache\\Storage\\WordPressObjectCacheStorage;\n\n[...]\n\n$stack-\u003epush(\n  new CacheMiddleware(\n    new PrivateCacheStrategy(\n      new WordPressObjectCacheStorage()\n    )\n  ),\n  'cache'\n);\n```\n\n## Public and shared\nIt's possible to add a public shared cache to the stack:\n```php\n[...]\nuse Doctrine\\Common\\Cache\\FilesystemCache;\nuse Doctrine\\Common\\Cache\\PredisCache;\nuse Kevinrob\\GuzzleCache\\Strategy\\PrivateCacheStrategy;\nuse Kevinrob\\GuzzleCache\\Strategy\\PublicCacheStrategy;\nuse Kevinrob\\GuzzleCache\\Storage\\DoctrineCacheStorage;\n\n[...]\n// Private caching\n$stack-\u003epush(\n  new CacheMiddleware(\n    new PrivateCacheStrategy(\n      new DoctrineCacheStorage(\n        new FilesystemCache('/tmp/')\n      )\n    )\n  ),\n  'private-cache'\n);\n\n// Public caching\n$stack-\u003epush(\n  new CacheMiddleware(\n    new PublicCacheStrategy(\n      new DoctrineCacheStorage(\n        new PredisCache(\n          new Predis\\Client('tcp://10.0.0.1:6379')\n        )\n      )\n    )\n  ),\n  'shared-cache'\n);\n```\n\n## Greedy caching\nIn some cases servers might send insufficient or no caching headers at all.\nUsing the greedy caching strategy allows defining an expiry TTL on your own while\ndisregarding any possibly present caching headers:\n```php\n[...]\nuse Kevinrob\\GuzzleCache\\KeyValueHttpHeader;\nuse Kevinrob\\GuzzleCache\\Strategy\\GreedyCacheStrategy;\nuse Kevinrob\\GuzzleCache\\Storage\\DoctrineCacheStorage;\nuse Doctrine\\Common\\Cache\\FilesystemCache;\n\n[...]\n// Greedy caching\n$stack-\u003epush(\n  new CacheMiddleware(\n    new GreedyCacheStrategy(\n      new DoctrineCacheStorage(\n        new FilesystemCache('/tmp/')\n      ),\n      1800, // the TTL in seconds\n      new KeyValueHttpHeader(['Authorization']) // Optional - specify the headers that can change the cache key\n    )\n  ),\n  'greedy-cache'\n);\n```\n\n## Delegate caching\nBecause your client may call different apps, on different domains, you may need to define which strategy is suitable to your requests.\n\nTo solve this, all you have to do is to define a default cache strategy, and override it by implementing your own Request Matchers.\n\nHere's an example:\n```php\nnamespace App\\RequestMatcher;\n\nuse Kevinrob\\GuzzleCache\\Strategy\\Delegate\\RequestMatcherInterface;\nuse Psr\\Http\\Message\\RequestInterface;\n\nclass ExampleOrgRequestMatcher implements RequestMatcherInterface\n{\n\n    /**\n     * @inheritDoc\n     */\n    public function matches(RequestInterface $request)\n    {\n        return false !== strpos($request-\u003egetUri()-\u003egetHost(), 'example.org');\n    }\n}\n```\n\n```php\nnamespace App\\RequestMatcher;\n\nuse Kevinrob\\GuzzleCache\\Strategy\\Delegate\\RequestMatcherInterface;\nuse Psr\\Http\\Message\\RequestInterface;\n\nclass TwitterRequestMatcher implements RequestMatcherInterface\n{\n\n    /**\n     * @inheritDoc\n     */\n    public function matches(RequestInterface $request)\n    {\n        return false !== strpos($request-\u003egetUri()-\u003egetHost(), 'twitter.com');\n    }\n}\n```\n\n```php\nrequire_once __DIR__ . '/vendor/autoload.php';\n\nuse App\\RequestMatcher\\ExampleOrgRequestMatcher;\nuse App\\RequestMatcher\\TwitterRequestMatcher;\nuse GuzzleHttp\\Client;\nuse GuzzleHttp\\HandlerStack;\nuse Kevinrob\\GuzzleCache\\CacheMiddleware;\nuse Kevinrob\\GuzzleCache\\Strategy;\n\n$strategy = new Strategy\\Delegate\\DelegatingCacheStrategy($defaultStrategy = new Strategy\\NullCacheStrategy());\n$strategy-\u003eregisterRequestMatcher(new ExampleOrgRequestMatcher(), new Strategy\\PublicCacheStrategy());\n$strategy-\u003eregisterRequestMatcher(new TwitterRequestMatcher(), new Strategy\\PrivateCacheStrategy());\n\n$stack = HandlerStack::create();\n$stack-\u003epush(new CacheMiddleware($strategy));\n$guzzle = new Client(['handler' =\u003e $stack]);\n```\n\nWith this example:\n* All requests to `example.org` will be handled by `PublicCacheStrategy`\n* All requests to `twitter.com` will be handled by `PrivateCacheStrategy`\n* All other requests won't be cached.\n\n## Drupal\nSee [Guzzle Cache](https://www.drupal.org/project/guzzle_cache) module.\n\n# Links that talk about the project\n- [Caching HTTP-Requests with Guzzle 6 and PSR-6](http://a.kabachnik.info/caching-http-requests-with-guzzle-6-and-psr-6.html)\n\n# Buy me a coffee\nIf you like this project, you can [buy me a coffee](https://buymeacoffee.com/kevinrob)! (or a beer 😉)  \n[\u003cimg src=\"bmc_qr.png\" width=\"200\"\u003e](https://buymeacoffee.com/kevinrob)\n\n# Development\n\n## Docker quick start\n\n### Initialization\n```bash\nmake init\n```\n### Running test\n```bash\nmake test\n```\n### Entering container shell\n```bash\nmake shell\n```\n","funding_links":["https://buymeacoffee.com/kevinrob)!","https://buymeacoffee.com/kevinrob"],"categories":["PHP"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKevinrob%2Fguzzle-cache-middleware","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKevinrob%2Fguzzle-cache-middleware","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKevinrob%2Fguzzle-cache-middleware/lists"}