|
1 | 1 | .. _message-factory:
|
| 2 | +.. _stream-factory: |
2 | 3 |
|
3 |
| -Message Factory |
4 |
| -=============== |
| 4 | +HTTP Factories |
| 5 | +============== |
5 | 6 |
|
6 |
| -**Factory interfaces for PSR-7 HTTP Message.** |
| 7 | +**Factory interfaces for PSR-7 HTTP objects.** |
7 | 8 |
|
8 | 9 | Rationale
|
9 | 10 | ---------
|
10 | 11 |
|
11 |
| -While it should be possible to use every PSR-7 aware HTTP client with any RequestInterface implementation, |
12 |
| -creating the request objects will still tie the code to a specific implementation. |
13 |
| -If each reusable library is tied to a specific message implementation, |
14 |
| -an application could end up installing several message implementations. |
15 |
| -The factories abstract away from this. |
| 12 | +While it should be possible to use every PSR-7 aware HTTP client with any |
| 13 | +request, URI and stream implementation, instantiating objects explicitly would |
| 14 | +still tie the code to a specific implementation. If each reusable library is |
| 15 | +tied to a specific message implementation, an application could end up |
| 16 | +installing several message implementations. The factories move instantiation |
| 17 | +out of the library code, further decoupling libraries from implementation. |
16 | 18 |
|
17 | 19 | The FIG was pretty straightforward by NOT putting any construction logic into PSR-7.
|
18 | 20 | The ``MessageFactory`` aims to provide an easy way to construct messages.
|
19 | 21 |
|
20 |
| -Usage |
21 |
| ------ |
22 |
| - |
23 |
| -.. _stream-factory: |
| 22 | +Factories |
| 23 | +--------- |
24 | 24 |
|
25 | 25 | The `php-http/message-factory` package defines interfaces for PSR-7 factories including:
|
26 | 26 |
|
27 |
| -- ``MessageFactory`` |
28 |
| -- ``ServerRequestFactory`` - WIP (PRs welcome) |
| 27 | +- ``RequestFactory`` |
| 28 | +- ``ResponseFactory`` |
| 29 | +- ``MessageFactory`` (combination of request and response factories) |
29 | 30 | - ``StreamFactory``
|
30 |
| -- ``UploadedFileFactory`` - WIP (PRs welcome) |
31 | 31 | - ``UriFactory``
|
32 | 32 |
|
33 |
| -Implementation for the interfaces above for `Diactoros`_ and `Guzzle PSR-7`_ and `Slim Framework`_ can be found in ``php-http/message``. |
34 |
| - |
35 |
| -.. code:: php |
| 33 | +Implementations of the interfaces above for `Diactoros`_, `Guzzle PSR-7`_ and the `Slim Framework`_ can be found in ``php-http/message``. |
36 | 34 |
|
37 |
| - // Create a PSR-7 request |
38 |
| - $factory = new Http\Message\MessageFactory\DiactorosMessageFactory(); |
39 |
| - $request = $factory->createRequest('GET', 'http://example.com'); |
40 |
| -
|
41 |
| - // Create a PSR-7 stream |
42 |
| - $factory = new Http\Message\StreamFactory\DiactorosStreamFactory(); |
43 |
| - $stream = $factory->createStream('stream content'); |
44 |
| -
|
45 |
| -You could also use :doc:`/discovery` to find an installed factory automatically. |
46 |
| - |
47 |
| -.. code:: php |
48 |
| -
|
49 |
| - // Create a PSR-7 request |
50 |
| - $factory = MessageFactoryDiscovery::find(); |
51 |
| - $request = $factory->createRequest('GET', 'http://example.com'); |
| 35 | +Usage |
| 36 | +----- |
52 | 37 |
|
| 38 | +Instantiate the factories in your bootstrap code or use discovery for them. |
| 39 | +Inject the factories into the rest of your code to limit the implementation |
| 40 | +choice to the bootstrapping code:: |
| 41 | + |
| 42 | + // ApiClient.php |
| 43 | + |
| 44 | + use Http\Message\RequestFactory; |
| 45 | + use Http\Message\StreamFactory; |
| 46 | + use Http\Message\UriFactory; |
| 47 | + |
| 48 | + class ApiClient |
| 49 | + { |
| 50 | + /** |
| 51 | + * @var RequestFactory |
| 52 | + */ |
| 53 | + private $requestFactory; |
| 54 | + |
| 55 | + /** |
| 56 | + * @var StreamFactory |
| 57 | + */ |
| 58 | + private $streamFactory; |
| 59 | + |
| 60 | + /** |
| 61 | + * @var UriFactory |
| 62 | + */ |
| 63 | + private $uriFactory; |
| 64 | + |
| 65 | + public function __construct( |
| 66 | + RequestFactory $requestFactory, |
| 67 | + StreamFactory $streamFactory, |
| 68 | + UriFactory $uriFactory |
| 69 | + ) { |
| 70 | + $this->requestFactory = $requestFactory; |
| 71 | + $this->streamFactory = $streamFactory; |
| 72 | + $this->uriFactory = $uriFactory; |
| 73 | + } |
| 74 | + |
| 75 | + public function doStuff() |
| 76 | + { |
| 77 | + $request = $this->requestFactory->createRequest('GET', 'http://httplug.io'); |
| 78 | + $stream = $this->streamFactory->createStream('stream content'); |
| 79 | + $uri = $this->UriFactory->createUri('http://httplug.io'); |
| 80 | + ... |
| 81 | + } |
| 82 | + } |
| 83 | + |
| 84 | +The bootstrapping code could look like this:: |
| 85 | + |
| 86 | + // bootstrap.php |
| 87 | + use Http\Message\MessageFactory\DiactorosMessageFactory; |
| 88 | + use Http\Message\StreamFactory\DiactorosStreamFactory; |
| 89 | + use Http\Message\UriFactory\DiactorosUriFactory; |
| 90 | + |
| 91 | + $apiClient = new ApiClient( |
| 92 | + new DiactorosMessageFactory(), |
| 93 | + new DiactorosStreamFactory(), |
| 94 | + new DiactorosUriFactory() |
| 95 | + ); |
| 96 | + |
| 97 | +You could also use :doc:`/discovery` to make the factory arguments optional and |
| 98 | +automatically find an available factory in the client:: |
| 99 | + |
| 100 | + // ApiClient.php |
| 101 | + |
| 102 | + use Http\Discovery\MessageFactoryDiscovery; |
| 103 | + use Http\Discovery\StreamFactoryDiscovery; |
| 104 | + use Http\Discovery\UriFactoryDiscovery; |
| 105 | + use Http\Message\RequestFactory; |
| 106 | + use Http\Message\StreamFactory; |
| 107 | + use Http\Message\UriFactory; |
| 108 | + |
| 109 | + class ApiClient |
| 110 | + { |
| 111 | + public function __construct( |
| 112 | + RequestFactory $requestFactory = null, |
| 113 | + StreamFactory $streamFactory = null, |
| 114 | + UriFactory $uriFactory = null |
| 115 | + ) { |
| 116 | + $this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find(), |
| 117 | + $this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find(); |
| 118 | + $this->uriFactory = $uriFactory ?: UriFactoryDiscovery::find();; |
| 119 | + } |
| 120 | + |
| 121 | + ... |
| 122 | + } |
| 123 | + |
| 124 | +.. hint:: |
| 125 | + |
| 126 | + If you create requests only and no responses, use ``RequestFactory`` in the |
| 127 | + type hint, instead of the ``MessageFactory``. And vice versa if you create |
| 128 | + responses only. |
| 129 | + |
| 130 | +Server Side Factories |
| 131 | +--------------------- |
| 132 | + |
| 133 | +It would make sense to also provide factories for the server side constructs |
| 134 | +``ServerRequestInterface`` and ``UploadedFileInterface``. We did not get around |
| 135 | +to do that yet. Contributions are welcome if you want to define the |
| 136 | +``ServerRequestFactory`` and ``UploadedFileFactory``. |
53 | 137 |
|
54 | 138 | .. _Diactoros: https://github.com/zendframework/zend-diactoros
|
55 | 139 | .. _Guzzle PSR-7: https://github.com/guzzle/psr7
|
56 | 140 | .. _Slim Framework: https://github.com/slimphp/Slim
|
57 |
| - |
|
0 commit comments