Skip to content

Commit 62af034

Browse files
GaryPEGEOTdbu
authored andcommitted
[Plugin] Add documentation for the VCR plugin (#262)
* Add documentation for the VCR plugin
1 parent 32e95e1 commit 62af034

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

plugins/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ request or you can even start a completely new request. This gives you full cont
2626
request-uri-manipulations
2727
retry
2828
stopwatch
29+
vcr

plugins/vcr.rst

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
VCR Plugin - Record and Replay Responses
2+
========================================
3+
4+
The VCR plugins allow you to record & replay HTTP responses. It's very useful for test purpose (using production-like predictable fixtures and avoid making actual HTTP request).
5+
You can also use it during your development cycle, when the endpoint you're contacting is not ready yet.
6+
7+
Unlike the :doc:`php-http/mock-client </clients/mock-client>`, where you have to manually define responses, the responses are **automatically** generated from the previously recorded ones.
8+
9+
Install
10+
-------
11+
12+
.. code-block:: bash
13+
14+
$ composer require --dev php-http/vcr-plugin
15+
16+
Usage
17+
-----
18+
19+
To record or replay a response, you will need two components, a **naming strategy** and a **recorder**.
20+
21+
The naming strategy
22+
*******************
23+
24+
The naming strategy turn a request into a deterministic and unique identifier.
25+
The identifier must be safe to use with a filesystem.
26+
The plugin provide a default naming strategy, the ``PathNamingStrategy``. You can define two options:
27+
28+
* **hash_headers**: the list of header(s) that make the request unique (Ex: 'Authorization'). The name & content of the header will be hashed to generate a unique signature. By default no header is used.
29+
* **hash_body_methods**: indicate for which request methods the body makes requests distinct. (Default: PUT, POST, PATCH)
30+
31+
This naming strategy will turn a GET request to https://example.org/my-path to the ``example.org_GET_my-path`` name, and optionally add hashes if the request
32+
contain a header defined in the options, or if the method is not idempotent.
33+
34+
To create your own strategy, you need to create a class implementing ``Http\Client\Plugin\Vcr\NamingStrategy\NamingStrategyInterface``.
35+
36+
The recorder
37+
************
38+
39+
The recorder records and replays responses. The plugin provides two recorders:
40+
41+
* ``FilesystemRecorder``: Saves the response on your filesystem using Symfony's `filesystem component`_ and `Guzzle PSR7`_ library.
42+
* ``InMemoryRecorder``: Saves the response in memory. **Response will be lost at the end of the running process**
43+
44+
To create your own recorder, you need to create a class implementing the following interfaces:
45+
46+
* ``Http\Client\Plugin\Vcr\Recorder\RecorderInterface`` used by the RecordPlugin.
47+
* ``Http\Client\Plugin\Vcr\Recorder\PlayerInterface`` used by the ReplayPlugin.
48+
49+
The plugins
50+
***********
51+
52+
There are two plugins, one to record responses, the other to replay them.
53+
54+
* ``Http\Client\Plugin\Vcr\ReplayPlugin``, use a ``PlayerInterface`` to replay previously recorded responses.
55+
* ``Http\Client\Plugin\Vcr\RecordPlugin``, use a ``RecorderInterface`` instance to record the responses,
56+
57+
Both plugins add a response header to indicate either under which name the response has been stored (RecordPlugin, ``X-VCR-RECORD`` header), or which response name has been used to replay the request (ReplayPlugin, ``X-VCR-REPLAYED`` header).
58+
59+
If you plan on using both plugins at the same time (Replay or Record), the ``ReplayPlugin`` **must always** come first.
60+
Please also note that by default, the ``ReplayPlugin`` throws an exception when it cannot replay a request. If you want the plugin to continue the request (possibly to the actual server), set the third constructor argument to ``false`` (See example below).
61+
62+
Example
63+
*******
64+
65+
.. code-block:: php
66+
67+
<?php
68+
69+
use Http\Client\Common\PluginClient;
70+
use Http\Client\Plugin\Vcr\NamingStrategy\PathNamingStrategy;
71+
use Http\Client\Plugin\Vcr\Recorder\FilesystemRecorder;
72+
use Http\Client\Plugin\Vcr\RecordPlugin;
73+
use Http\Client\Plugin\Vcr\ReplayPlugin;
74+
use Http\Discovery\HttpClientDiscovery;
75+
76+
$namingStrategy = new PathNamingStrategy([
77+
'hash_headers' => ['X-Custom-Header'], // None by default
78+
'hash_body_methods' => ['POST'], // Default: PUT, POST, PATCH
79+
]);
80+
$recorder = new FilesystemRecorder('some/dir/in/vcs'); // You can use InMemoryRecorder as well
81+
82+
// To record responses:
83+
$record = new RecordPlugin($namingStrategy, $recorder);
84+
85+
// To replay responses:
86+
// Third argument prevent the plugin from throwing an exception when a request cannot be replayed
87+
$replay = new ReplayPlugin($namingStrategy, $recorder, false);
88+
89+
$pluginClient = new PluginClient(
90+
HttpClientDiscovery::find(),
91+
[$replay, $record] // Replay should always go first
92+
);
93+
94+
/** @var \Psr\Http\Message\RequestInterface $request */
95+
$request = new MyRequest('GET', 'https://httplug.io');
96+
97+
// Will be recorded in "some/dir/in/vcs"
98+
$client->sendRequest($request);
99+
100+
// Will be replayed from "some/dir/in/vcs"
101+
$client->sendRequest($request);
102+
103+
.. _filesystem component: https://symfony.com/doc/current/components/filesystem.html
104+
.. _Guzzle PSR7: https://github.com/guzzle/psr7

0 commit comments

Comments
 (0)