-
Notifications
You must be signed in to change notification settings - Fork 56
improve factories documentation #161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
* Use :doc:`plugins </plugins/introduction>` to customize the way HTTP requests are sent and | ||
responses processed by following redirects, adding Authentication or Cookie | ||
headers and more. | ||
* Learn how you can decouple your code from any PSR-7 implementation by using a | ||
:ref:`message factory <message-factory>`. | ||
* Learn how you can decouple your code from any PSR-7 implementation by using | ||
the :ref:`HTTP factories <message-factory>`. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,57 +1,140 @@ | ||
.. _message-factory: | ||
.. _stream-factory: | ||
|
||
Message Factory | ||
=============== | ||
HTTP Factories | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although I agree that they are not really Message Factories in most places we refer to them as message factories. The file name also says message-factory, so this could be a little bit confusing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that was the initial question in #141. i find "Message Factory" wrong here. what should we call it? "Message Factories" is wrong, uri and stream are not messages. other ideas? or should i hunt through the doc and change "message factory" to "http factory" where i find that? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I am all for consistency. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i adjusted some of the naming. in many places, we do explicitly mean a message factory and not any http factory. |
||
============== | ||
|
||
**Factory interfaces for PSR-7 HTTP Message.** | ||
**Factory interfaces for PSR-7 HTTP objects.** | ||
|
||
Rationale | ||
--------- | ||
|
||
While it should be possible to use every PSR-7 aware HTTP client with any RequestInterface implementation, | ||
creating the request objects will still tie the code to a specific implementation. | ||
If each reusable library is tied to a specific message implementation, | ||
an application could end up installing several message implementations. | ||
The factories abstract away from this. | ||
While it should be possible to use every PSR-7 aware HTTP client with any | ||
request, URI and stream implementation, instantiating objects explicitly would | ||
still tie the code to a specific implementation. If each reusable library is | ||
tied to a specific message implementation, an application could end up | ||
installing several message implementations. The factories move instantiation | ||
out of the library code, further decoupling libraries from implementation. | ||
|
||
The FIG was pretty straightforward by NOT putting any construction logic into PSR-7. | ||
The ``MessageFactory`` aims to provide an easy way to construct messages. | ||
|
||
Usage | ||
----- | ||
|
||
.. _stream-factory: | ||
Factories | ||
--------- | ||
|
||
The `php-http/message-factory` package defines interfaces for PSR-7 factories including: | ||
|
||
- ``MessageFactory`` | ||
- ``ServerRequestFactory`` - WIP (PRs welcome) | ||
- ``RequestFactory`` | ||
- ``ResponseFactory`` | ||
- ``MessageFactory`` (combination of request and response factories) | ||
- ``StreamFactory`` | ||
- ``UploadedFileFactory`` - WIP (PRs welcome) | ||
- ``UriFactory`` | ||
|
||
Implementation for the interfaces above for `Diactoros`_ and `Guzzle PSR-7`_ and `Slim Framework`_ can be found in ``php-http/message``. | ||
|
||
.. code:: php | ||
Implementations of the interfaces above for `Diactoros`_, `Guzzle PSR-7`_ and the `Slim Framework`_ can be found in ``php-http/message``. | ||
|
||
// Create a PSR-7 request | ||
$factory = new Http\Message\MessageFactory\DiactorosMessageFactory(); | ||
$request = $factory->createRequest('GET', 'http://example.com'); | ||
|
||
// Create a PSR-7 stream | ||
$factory = new Http\Message\StreamFactory\DiactorosStreamFactory(); | ||
$stream = $factory->createStream('stream content'); | ||
|
||
You could also use :doc:`/discovery` to find an installed factory automatically. | ||
|
||
.. code:: php | ||
|
||
// Create a PSR-7 request | ||
$factory = MessageFactoryDiscovery::find(); | ||
$request = $factory->createRequest('GET', 'http://example.com'); | ||
Usage | ||
----- | ||
|
||
Instantiate the factories in your bootstrap code or use discovery for them. | ||
Inject the factories into the rest of your code to limit the implementation | ||
choice to the bootstrapping code:: | ||
|
||
// ApiClient.php | ||
|
||
use Http\Message\RequestFactory; | ||
use Http\Message\StreamFactory; | ||
use Http\Message\UriFactory; | ||
|
||
class ApiClient | ||
{ | ||
/** | ||
* @var RequestFactory | ||
*/ | ||
private $requestFactory; | ||
|
||
/** | ||
* @var StreamFactory | ||
*/ | ||
private $streamFactory; | ||
|
||
/** | ||
* @var UriFactory | ||
*/ | ||
private $uriFactory; | ||
|
||
public function __construct( | ||
RequestFactory $requestFactory, | ||
StreamFactory $streamFactory, | ||
UriFactory $uriFactory | ||
) { | ||
$this->requestFactory = $requestFactory; | ||
$this->streamFactory = $streamFactory; | ||
$this->uriFactory = $uriFactory; | ||
} | ||
|
||
public function doStuff() | ||
{ | ||
$request = $this->requestFactory->createRequest('GET', 'http://httplug.io'); | ||
$stream = $this->streamFactory->createStream('stream content'); | ||
$uri = $this->UriFactory->createUri('http://httplug.io'); | ||
... | ||
} | ||
} | ||
|
||
The bootstrapping code could look like this:: | ||
|
||
// bootstrap.php | ||
use Http\Message\MessageFactory\DiactorosMessageFactory; | ||
use Http\Message\StreamFactory\DiactorosStreamFactory; | ||
use Http\Message\UriFactory\DiactorosUriFactory; | ||
|
||
$apiClient = new ApiClient( | ||
new DiactorosMessageFactory(), | ||
new DiactorosStreamFactory(), | ||
new DiactorosUriFactory() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You would rarely use the URI Factory since it is required by the message factory. I suggest removing it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hm. i want to show how to create all 3 factories in the example. and i guess there are use cases where you e.g. accept a url string and create the uri from it in your api client to do some uri manipulations before creating the request. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are you ok if we leave this as is? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am fine with that |
||
); | ||
|
||
You could also use :doc:`/discovery` to make the factory arguments optional and | ||
automatically find an available factory in the client:: | ||
|
||
// ApiClient.php | ||
|
||
use Http\Discovery\MessageFactoryDiscovery; | ||
use Http\Discovery\StreamFactoryDiscovery; | ||
use Http\Discovery\UriFactoryDiscovery; | ||
use Http\Message\RequestFactory; | ||
use Http\Message\StreamFactory; | ||
use Http\Message\UriFactory; | ||
|
||
class ApiClient | ||
{ | ||
public function __construct( | ||
RequestFactory $requestFactory = null, | ||
StreamFactory $streamFactory = null, | ||
UriFactory $uriFactory = null | ||
) { | ||
$this->requestFactory = $requestFactory ?: MessageFactoryDiscovery::find(), | ||
$this->streamFactory = $streamFactory ?: StreamFactoryDiscovery::find(); | ||
$this->uriFactory = $uriFactory ?: UriFactoryDiscovery::find();; | ||
} | ||
|
||
... | ||
} | ||
|
||
.. hint:: | ||
|
||
If you create requests only and no responses, use ``RequestFactory`` in the | ||
type hint, instead of the ``MessageFactory``. And vice versa if you create | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. spelling does not like this. is this proper english or not? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually it's latin, but should be ok. Just add it to the spellcheck list. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Already see this in english, you can also use "And conversely" if you want, but i think "vice versa" is better. |
||
responses only. | ||
|
||
Server Side Factories | ||
--------------------- | ||
|
||
It would make sense to also provide factories for the server side constructs | ||
``ServerRequestInterface`` and ``UploadedFileInterface``. We did not get around | ||
to do that yet. Contributions are welcome if you want to define the | ||
``ServerRequestFactory`` and ``UploadedFileFactory``. | ||
|
||
.. _Diactoros: https://github.com/zendframework/zend-diactoros | ||
.. _Guzzle PSR-7: https://github.com/guzzle/psr7 | ||
.. _Slim Framework: https://github.com/slimphp/Slim | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -30,6 +30,7 @@ sublicense | |
sync | ||
toolbar | ||
username | ||
versa | ||
whitelist | ||
wiki | ||
Wikipedia | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this file is still named message-factory.rst, which shows in the url. but i think as the package is called message-factory as well, its ok to keep that name.