@@ -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