Skip to content

Commit fa6a0c2

Browse files
authored
Merge pull request #103 from php-http/http_client_router
Add documentation for HTTP Client router
2 parents 953d338 + 9eca7ce commit fa6a0c2

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

components/client-common.rst

+76
Original file line numberDiff line numberDiff line change
@@ -152,3 +152,79 @@ RandomClientPool
152152
****************
153153

154154
``RandomClientPool`` randomly choose an available client, throw a ``NotFoundHttpClientException`` if none are available.
155+
156+
157+
HTTP Client Router
158+
------------------
159+
160+
This client accepts pairs of clients and request matchers.
161+
Every request is "routed" through the ``HttpClientRouter``, checked against the request matchers
162+
and sent using the first matched client. If there is no matching client, an exception is thrown.
163+
164+
This allows a single client to be used for different requests.
165+
166+
In the following example we use the client router to access an API protected by basic auth
167+
and also to download an image from a static host::
168+
169+
use Http\Client\Common\HttpClientRouter;
170+
use Http\Client\Common\PluginClient;
171+
use Http\Client\Common\Plugin\AuthenticationPlugin;
172+
use Http\Client\Common\Plugin\CachePlugin;
173+
use Http\Discovery\HttpClientDiscovery;
174+
use Http\Discovery\MessageFactoryDiscovery;
175+
use Http\Message\Authentication\BasicAuth;
176+
use Http\Message\RequestMatcher\RequestMatcher;
177+
178+
$client = new HttpClientRouter();
179+
180+
$requestMatcher = new RequestMatcher(null, 'api.example.com');
181+
$pluginClient = new PluginClient(
182+
HttpClientDiscovery::find(),
183+
[new AuthenticationPlugin(new BasicAuth('user', 'password'))]
184+
);
185+
186+
$client->addClient($pluginClient, $requestMatcher);
187+
188+
189+
$requestMatcher = new RequestMatcher(null, 'images.example.com');
190+
191+
/** @var \Psr\Cache\CacheItemPoolInterface $pool */
192+
$pool = ...
193+
/** @var \Http\Message\StreamFactory $streamFactory */
194+
$streamFactory = ...
195+
196+
$pluginClient = new PluginClient(
197+
HttpClientDiscovery::find(),
198+
[new CachePlugin($pool, $streamFactory)]
199+
);
200+
201+
$client->addClient($pluginClient, $requestMatcher);
202+
203+
204+
$messageFactory = MessageFactoryDiscovery::find();
205+
206+
// Get the user data
207+
$request = $messageFactory->createRequest('GET', 'https://api.example.com/user/1');
208+
209+
$response = $client->send($request);
210+
$imagePath = json_decode((string) $response->getBody(), true)['image_path'];
211+
212+
// Download the image and store it in cache
213+
$request = $messageFactory->createRequest('GET', 'https://images.example.com/user/'.$imagePath);
214+
215+
$response = $client->send($request);
216+
217+
file_put_contents('path/to/images/'.$imagePath, (string) $response->getBody());
218+
219+
$request = $messageFactory->createRequest('GET', 'https://api2.example.com/user/1');
220+
221+
// Throws an Http\Client\Exception\RequestException
222+
$client->send($request);
223+
224+
225+
.. note::
226+
227+
When you have small difference between the underlying clients (for example different credentials based on host)
228+
it's easier to use the ``RequestConditionalPlugin`` and the ``PluginClient``,
229+
but in that case the routing logic is integrated into the linear request flow
230+
which might make debugging harder.

0 commit comments

Comments
 (0)