Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
# guzzle-cache-middleware
2
 
3
[![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)
4
![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)
5
 
6
 
7
A HTTP Cache for [Guzzle](https://github.com/guzzle/guzzle) 6+. It's a simple Middleware to be added in the HandlerStack.
8
 
9
## Goals
10
- RFC 7234 compliance
11
- Performance and transparency
12
- Assured compatibility with PSR-7
13
 
14
## Built-in storage interfaces
15
- [Doctrine cache](https://github.com/doctrine/cache)
16
- [Laravel cache](https://laravel.com/docs/5.2/cache)
17
- [Flysystem](https://github.com/thephpleague/flysystem)
18
- [PSR6](https://github.com/php-fig/cache)
19
- [WordPress Object Cache](https://codex.wordpress.org/Class_Reference/WP_Object_Cache)
20
 
21
## Installation
22
 
23
`composer require kevinrob/guzzle-cache-middleware`
24
 
25
or add it the your `composer.json` and run `composer update kevinrob/guzzle-cache-middleware`.
26
 
27
# Why?
28
Performance. It's very common to do some HTTP calls to an API for rendering a page and it takes times to do it.
29
 
30
# How?
31
With a simple Middleware added at the top of the `HandlerStack` of Guzzle.
32
 
33
```php
34
use GuzzleHttp\Client;
35
use GuzzleHttp\HandlerStack;
36
use Kevinrob\GuzzleCache\CacheMiddleware;
37
 
38
// Create default HandlerStack
39
$stack = HandlerStack::create();
40
 
41
// Add this middleware to the top with `push`
42
$stack->push(new CacheMiddleware(), 'cache');
43
 
44
// Initialize the client with the handler option
45
$client = new Client(['handler' => $stack]);
46
```
47
 
48
# Examples
49
 
50
## Doctrine/Cache
51
You can use a cache from `Doctrine/Cache`:
52
```php
53
[...]
54
use Doctrine\Common\Cache\FilesystemCache;
55
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
56
use Kevinrob\GuzzleCache\Storage\DoctrineCacheStorage;
57
 
58
[...]
59
$stack->push(
60
  new CacheMiddleware(
61
    new PrivateCacheStrategy(
62
      new DoctrineCacheStorage(
63
        new FilesystemCache('/tmp/')
64
      )
65
    )
66
  ),
67
  'cache'
68
);
69
```
70
 
71
You 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.
72
```php
73
[...]
74
use Doctrine\Common\Cache\ChainCache;
75
use Doctrine\Common\Cache\ArrayCache;
76
use Doctrine\Common\Cache\FilesystemCache;
77
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
78
use Kevinrob\GuzzleCache\Storage\DoctrineCacheStorage;
79
 
80
[...]
81
$stack->push(new CacheMiddleware(
82
  new PrivateCacheStrategy(
83
    new DoctrineCacheStorage(
84
      new ChainCache([
85
        new ArrayCache(),
86
        new FilesystemCache('/tmp/'),
87
      ])
88
    )
89
  )
90
), 'cache');
91
```
92
 
93
## Laravel cache
94
You can use a cache with Laravel, e.g. Redis, Memcache etc.:
95
```php
96
[...]
97
use Illuminate\Support\Facades\Cache;
98
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
99
use Kevinrob\GuzzleCache\Storage\LaravelCacheStorage;
100
 
101
[...]
102
 
103
$stack->push(
104
  new CacheMiddleware(
105
    new PrivateCacheStrategy(
106
      new LaravelCacheStorage(
107
        Cache::store('redis')
108
      )
109
    )
110
  ),
111
  'cache'
112
);
113
```
114
 
115
## Flysystem
116
```php
117
[...]
118
use League\Flysystem\Adapter\Local;
119
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
120
use Kevinrob\GuzzleCache\Storage\FlysystemStorage;
121
 
122
[...]
123
 
124
$stack->push(
125
  new CacheMiddleware(
126
    new PrivateCacheStrategy(
127
      new FlysystemStorage(
128
        new Local('/path/to/cache')
129
      )
130
    )
131
  ),
132
  'cache'
133
);
134
```
135
 
136
## WordPress Object Cache
137
```php
138
[...]
139
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
140
use Kevinrob\GuzzleCache\Storage\WordPressObjectCacheStorage;
141
 
142
[...]
143
 
144
$stack->push(
145
  new CacheMiddleware(
146
    new PrivateCacheStrategy(
147
      new WordPressObjectCacheStorage()
148
    )
149
  ),
150
  'cache'
151
);
152
```
153
 
154
## Public and shared
155
It's possible to add a public shared cache to the stack:
156
```php
157
[...]
158
use Doctrine\Common\Cache\FilesystemCache;
159
use Doctrine\Common\Cache\PredisCache;
160
use Kevinrob\GuzzleCache\Strategy\PrivateCacheStrategy;
161
use Kevinrob\GuzzleCache\Strategy\PublicCacheStrategy;
162
use Kevinrob\GuzzleCache\Storage\DoctrineCacheStorage;
163
 
164
[...]
165
// Private caching
166
$stack->push(
167
  new CacheMiddleware(
168
    new PrivateCacheStrategy(
169
      new DoctrineCacheStorage(
170
        new FilesystemCache('/tmp/')
171
      )
172
    )
173
  ),
174
  'private-cache'
175
);
176
 
177
// Public caching
178
$stack->push(
179
  new CacheMiddleware(
180
    new PublicCacheStrategy(
181
      new DoctrineCacheStorage(
182
        new PredisCache(
183
          new Predis\Client('tcp://10.0.0.1:6379')
184
        )
185
      )
186
    )
187
  ),
188
  'shared-cache'
189
);
190
```
191
 
192
## Greedy caching
193
In some cases servers might send insufficient or no caching headers at all.
194
Using the greedy caching strategy allows defining an expiry TTL on your own while
195
disregarding any possibly present caching headers:
196
```php
197
[...]
198
use Kevinrob\GuzzleCache\KeyValueHttpHeader;
199
use Kevinrob\GuzzleCache\Strategy\GreedyCacheStrategy;
200
use Kevinrob\GuzzleCache\Storage\DoctrineCacheStorage;
201
use Doctrine\Common\Cache\FilesystemCache;
202
 
203
[...]
204
// Greedy caching
205
$stack->push(
206
  new CacheMiddleware(
207
    new GreedyCacheStrategy(
208
      new DoctrineCacheStorage(
209
        new FilesystemCache('/tmp/')
210
      ),
211
      1800, // the TTL in seconds
212
      new KeyValueHttpHeader(['Authorization']) // Optional - specify the headers that can change the cache key
213
    )
214
  ),
215
  'greedy-cache'
216
);
217
```
218
 
219
## Delegate caching
220
Because your client may call different apps, on different domains, you may need to define which strategy is suitable to your requests.
221
 
222
To solve this, all you have to do is to define a default cache strategy, and override it by implementing your own Request Matchers.
223
 
224
Here's an example:
225
```php
226
namespace App\RequestMatcher;
227
 
228
use Kevinrob\GuzzleCache\Strategy\Delegate\RequestMatcherInterface;
229
use Psr\Http\Message\RequestInterface;
230
 
231
class ExampleOrgRequestMatcher implements RequestMatcherInterface
232
{
233
 
234
    /**
235
     * @inheritDoc
236
     */
237
    public function matches(RequestInterface $request)
238
    {
239
        return false !== strpos($request->getUri()->getHost(), 'example.org');
240
    }
241
}
242
```
243
 
244
```php
245
namespace App\RequestMatcher;
246
 
247
use Kevinrob\GuzzleCache\Strategy\Delegate\RequestMatcherInterface;
248
use Psr\Http\Message\RequestInterface;
249
 
250
class TwitterRequestMatcher implements RequestMatcherInterface
251
{
252
 
253
    /**
254
     * @inheritDoc
255
     */
256
    public function matches(RequestInterface $request)
257
    {
258
        return false !== strpos($request->getUri()->getHost(), 'twitter.com');
259
    }
260
}
261
```
262
 
263
```php
264
require_once __DIR__ . '/vendor/autoload.php';
265
 
266
use App\RequestMatcher\ExampleOrgRequestMatcher;
267
use App\RequestMatcher\TwitterRequestMatcher;
268
use GuzzleHttp\Client;
269
use GuzzleHttp\HandlerStack;
270
use Kevinrob\GuzzleCache\CacheMiddleware;
271
use Kevinrob\GuzzleCache\Strategy;
272
 
273
$strategy = new Strategy\Delegate\DelegatingCacheStrategy($defaultStrategy = new Strategy\NullCacheStrategy());
274
$strategy->registerRequestMatcher(new ExampleOrgRequestMatcher(), new Strategy\PublicCacheStrategy());
275
$strategy->registerRequestMatcher(new TwitterRequestMatcher(), new Strategy\PrivateCacheStrategy());
276
 
277
$stack = HandlerStack::create();
278
$stack->push(new CacheMiddleware($strategy));
279
$guzzle = new Client(['handler' => $stack]);
280
```
281
 
282
With this example:
283
* All requests to `example.org` will be handled by `PublicCacheStrategy`
284
* All requests to `twitter.com` will be handled by `PrivateCacheStrategy`
285
* All other requests won't be cached.
286
 
287
## Drupal
288
See [Guzzle Cache](https://www.drupal.org/project/guzzle_cache) module.
289
 
290
# Links that talk about the project
291
- [Speeding Up APIs/Apps/Smart Toasters with HTTP Response Caching](https://apisyouwonthate.com/blog/speeding-up-apis-apps-smart-toasters-with-http-response-caching)
292
- [Caching HTTP-Requests with Guzzle 6 and PSR-6](http://a.kabachnik.info/caching-http-requests-with-guzzle-6-and-psr-6.html)