Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Greedy cache strategy improvements #83

Merged
merged 2 commits into from
Jul 9, 2017
Merged

Greedy cache strategy improvements #83

merged 2 commits into from
Jul 9, 2017

Conversation

bpolaszek
Copy link
Contributor

@bpolaszek bpolaszek commented Jul 7, 2017

Hi there,

TL; DR;

New feature: allow GreedyCacheStrategy to generate the cache key based on specific headers.

Introduction

I'm currently working with several heavy partner APIs that don't care much about cache headers.
So I'm using the GreedyCacheStrategy to cache their responses.
Problem: I use several accounts for these APIs, within the same app. To describe this in gherkin language:

Background:
  Given I'm authenticated on the API with UserA
  And I have fetched http://some-api.com/campaigns
  And The response has been stored in the cache

  Scenario: Ask the same resource for another user
    When I authenticate on the API with UserB
    And I fetch http://some-api.com/campaigns
    Then I should not get UserA's campaigns
    But I should get UserB's campaigns
    And The response should be stored in the cache

Currently, when I'm logged in with UserA, and I fetch and cache the resource /campaigns, and then, later, I log in as UserB, and I fetch the same resource /campaigns, I get UserA's cached campaigns.

To prevent this behaviour, I added an option into the GreedyCacheStrategy that allow to specify a KeyValueHttpHeader into its constructor, which will help in generating a different cache key, based on specific headers.

Example

require_once __DIR__ . '/vendor/autoload.php';

use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Request;
use Kevinrob\GuzzleCache\CacheMiddleware;
use Kevinrob\GuzzleCache\KeyValueHttpHeader;
use Kevinrob\GuzzleCache\Strategy\GreedyCacheStrategy;

$stack = HandlerStack::create();
$stack->push(new CacheMiddleware(
    new GreedyCacheStrategy(
        null,
        10,
        new KeyValueHttpHeader(['Authorization'])
    )
));
$guzzle = new Client(['handler' => $stack]);

$request = new Request('GET', 'http://httpbin.org/get');
$billGates = 'Microsoft is great';
$timCook = 'Apple is better';

$responses = [
    $guzzle->send($request->withAddedHeader('Authorization', 'Bearer: ' . $billGates)),
    $guzzle->send($request->withAddedHeader('Authorization', 'Bearer: ' . $timCook)),
    $guzzle->send($request->withAddedHeader('Authorization', 'Bearer: ' . $billGates)),
];

var_dump($responses[0]->getHeaderLine('X-Kevinrob-Cache')); // MISS
var_dump($responses[1]->getHeaderLine('X-Kevinrob-Cache')); // MISS
var_dump($responses[2]->getHeaderLine('X-Kevinrob-Cache')); // HIT

There's no BC break since it's a new, optionnal feature.
When no KeyValueHttpHeader is provided, the sha is still the same as before.

@Kevinrob
Copy link
Owner

Kevinrob commented Jul 9, 2017

Thank you for this PR! I will check it.

@Kevinrob Kevinrob merged commit c21d8ce into Kevinrob:master Jul 9, 2017
@bpolaszek
Copy link
Contributor Author

Thanks @Kevinrob!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants