@@ -609,14 +609,57 @@ regular expression applied to relative URLs::
609
609
'https://api\.github\.com/'
610
610
);
611
611
612
- PSR-18 Compatibility
613
- --------------------
612
+ Interoperability
613
+ ----------------
614
+
615
+ The component is interoperable with 3 different abstractions for HTTP clients:
616
+ `Symfony Contracts `_, `PSR-18 `_ and `HTTPlug `_ v1 and v2. If your app uses
617
+ libraries that need any of them, the component is compatible with them.
618
+ They also benefit from autowiring aliases when the
619
+ :ref: `framework bundle <framework-bundle-configuration >` is used.
620
+
621
+ If you are writing or maintaining a library that makes HTTP requests, you can
622
+ decouple it from any specific HTTP client implementations by coding against
623
+ either Symfony Contracts (recommended) or PSR-18 (which superseded HTTPlug).
624
+
625
+ Symfony Contracts
626
+ ~~~~~~~~~~~~~~~~~
627
+
628
+ The interfaces found in the ``symfony/http-client-contracts `` package define
629
+ the primary abstractions implemented by the component. Its entry point is the
630
+ :class: `Symfony\\ Contracts\\ HttpClient\\ HttpClientInterface `. That's the
631
+ interface you need to code against when a client is needed::
614
632
615
- This component uses and implements abstractions defined by the
616
- ``symfony/http-client-contracts ``. It also implements the `PSR-18 `_ (HTTP Client)
617
- specifications via the :class: `Symfony\\ Component\\ HttpClient\\ Psr18Client `
618
- class, which is an adapter to turn a Symfony ``HttpClientInterface `` into a
619
- PSR-18 ``ClientInterface ``.
633
+ use Symfony\Contracts\HttpClient\HttpClientInterface;
634
+
635
+ class MyApiLayer
636
+ {
637
+ private $client;
638
+
639
+ public function __construct(HttpClientInterface $client)
640
+ {
641
+ $this->client = $client
642
+ }
643
+
644
+ // [...]
645
+ }
646
+
647
+ All request options mentionned above (e.g. timeout management) are also defined
648
+ in the wordings of the interface, so that any compliant implementations (like this
649
+ component) is guaranteed to provide them. That's a major difference with the
650
+ PSR-18 abstraction, which provides none related to the transport itself.
651
+
652
+ Another major feature covered by the Symfony Contracts is async/multiplexing,
653
+ as described in the previous sections.
654
+
655
+ PSR-18 and PSR-17
656
+ ~~~~~~~~~~~~~~~~~
657
+
658
+ This component implements the `PSR-18 `_ (HTTP Client) specifications via the
659
+ :class: `Symfony\\ Component\\ HttpClient\\ Psr18Client ` class, which is an adapter
660
+ to turn a Symfony ``HttpClientInterface `` into a PSR-18 ``ClientInterface ``.
661
+ This class also implements the relevant methods of `PSR-17 `_ to ease creating
662
+ request objects.
620
663
621
664
To use it, you need the ``psr/http-client `` package and a `PSR-17 `_ implementation:
622
665
@@ -631,18 +674,73 @@ To use it, you need the ``psr/http-client`` package and a `PSR-17`_ implementati
631
674
632
675
Now you can make HTTP requests with the PSR-18 client as follows::
633
676
634
- use Nyholm\Psr7\Factory\Psr17Factory;
635
677
use Symfony\Component\HttpClient\Psr18Client;
636
678
637
- $psr17Factory = new Psr17Factory();
638
- $psr18Client = new Psr18Client();
679
+ $client = new Psr18Client();
639
680
640
681
$url = 'https://symfony.com/versions.json';
641
- $request = $psr17Factory ->createRequest('GET', $url);
642
- $response = $psr18Client ->sendRequest($request);
682
+ $request = $client ->createRequest('GET', $url);
683
+ $response = $client ->sendRequest($request);
643
684
644
685
$content = json_decode($response->getBody()->getContents(), true);
645
686
687
+ .. versionadded :: 4.4
688
+
689
+ The PSR-17 factory methods have been added to ``Psr18Client `` in Symfony 4.4.
690
+
691
+ HTTPlug
692
+ ~~~~~~~
693
+
694
+ .. versionadded :: 4.4
695
+
696
+ Support for HTTPlug was added in Symfony 4.4.
697
+
698
+ The `HTTPlug `_ specification pre-dates and is superseded by PSR-18. As such, you
699
+ should not use it in newly written code. Yet, many libraries still require v1 or
700
+ v2 of it. The component is interoperable with them thanks to the ``HttplugClient ``
701
+ adapter class that it provides. Similarly to ``Psr18Client `` implementing
702
+ relevant parts of PSR-17, ``HttplugClient `` also implements the factory methods
703
+ defined in the related ``php-http/message-factory `` package.
704
+
705
+ Internally, the implementation relies on the ``Psr18Client ``, so that the
706
+ ``psr/http-client `` package is needed to use this class::
707
+
708
+ .. code-block :: terminal
709
+
710
+ # Let's suppose php-http/httplug is already required by the lib you want to use
711
+
712
+ # installs the PSR-18 ClientInterface
713
+ $ composer require psr/http-client
714
+
715
+ # installs an efficient implementation of response and stream factories
716
+ # with autowiring aliases provided by Symfony Flex
717
+ $ composer require nyholm/psr7
718
+
719
+ Let's say you want to instantiate a class with the following constructor,
720
+ that requires HTTPlug dependencies::
721
+
722
+ use Http\Client\HttpClient;
723
+ use Http\Message\RequestFactory;
724
+ use Http\Message\StreamFactory;
725
+
726
+ class SomeSdk
727
+ {
728
+ public function __construct(
729
+ HttpClient $httpClient,
730
+ RequestFactory $requestFactory,
731
+ StreamFactory $streamFactory
732
+ )
733
+ // [...]
734
+ }
735
+
736
+ Because ``HttplugClient `` implements the 3 interfaces, you can use it this way::
737
+
738
+ use Symfony\Component\HttpClient\HttplugClient;
739
+
740
+ $httpClient = new HttplugClient();
741
+
742
+ $apiClient = new SomeSdk($httpClient, $httpClient, $httpClient);
743
+
646
744
Symfony Framework Integration
647
745
-----------------------------
648
746
@@ -765,3 +863,5 @@ However, using ``MockResponse`` allows simulating chunked responses and timeouts
765
863
.. _`cURL PHP extension` : https://php.net/curl
766
864
.. _`PSR-17` : https://www.php-fig.org/psr/psr-17/
767
865
.. _`PSR-18` : https://www.php-fig.org/psr/psr-18/
866
+ .. _`HTTPlug` : https://github.com/php-http/httplug/#readme
867
+ .. _`Symfony Contracts` : https://github.com/symfony/contracts
0 commit comments