From 95fed70c1273151811ea25248a6baa2df85c36ee Mon Sep 17 00:00:00 2001 From: David de Boer Date: Sun, 3 Jan 2016 13:34:15 +0100 Subject: [PATCH 1/2] Merge HTTPlug intro and re-group TOC --- clients.rst | 4 ++- conf.py | 1 + httplug.rst | 29 --------------- httplug/introduction.rst | 77 ++++++++++++++++++++++------------------ httplug/usage.rst | 17 +++++++++ index.rst | 26 +++++--------- 6 files changed, 73 insertions(+), 81 deletions(-) delete mode 100644 httplug.rst create mode 100644 httplug/usage.rst diff --git a/clients.rst b/clients.rst index cb9d1a2..5a1efcd 100644 --- a/clients.rst +++ b/clients.rst @@ -4,7 +4,9 @@ Clients & Adapters There are clients implementing one of the HTTPlug interfaces directly, and adapter packages that implement the interface and forward the calls to HTTP clients not implementing the interface. -TODO +.. _`php-http/client-implementation`: https://packagist.org/providers/php-http/client-implementation +.. _`php-http/async-client-implementation`: https://packagist.org/providers/php-http/async-client-implementation: + Clients: diff --git a/conf.py b/conf.py index 573268c..9052114 100644 --- a/conf.py +++ b/conf.py @@ -301,4 +301,5 @@ rst_epilog = """ .. _PSR-7: http://www.php-fig.org/psr/psr-7 .. _Composer: https://getcomposer.org +.. _HttplugBundle: https://github.com/php-http/HttplugBundle """ diff --git a/httplug.rst b/httplug.rst deleted file mode 100644 index eb59051..0000000 --- a/httplug.rst +++ /dev/null @@ -1,29 +0,0 @@ -HTTPlug: HTTP client abstraction -================================ - -HTTPlug is an abstraction for HTTP clients. There are two main use cases: - -1. Usage in a project/application -2. Usage in a reusable package - -In both cases, the ``Http\Client\HttpClient`` provides a ``sendRequest`` method -to send a PSR-7 ``RequestInterface`` and returns a PSR-7 ``ResponseInterface`` -or throws an exception that implements ``Http\Client\Exception``. - -There is also the ``Http\Client\HttpAsyncClient`` which provides the -``sendAsyncRequest`` method to send a request asynchronously and returns a -``Http\Client\Promise``. - -The promise allows to specify handlers for a PSR-7 ``ResponseInterface`` -or an exception that implements ``Http\Client\Exception``. - -See the :doc:`tutorial ` for a concrete example. - - -.. toctree:: - - Introduction - Tutorial - Migrating - Virtual Package - diff --git a/httplug/introduction.rst b/httplug/introduction.rst index fe73bef..b954edc 100644 --- a/httplug/introduction.rst +++ b/httplug/introduction.rst @@ -1,32 +1,48 @@ -Introduction to HTTPlug -======================= +HTTPlug: HTTP client abstraction +================================ -HTTPlug implementations ------------------------ +HTTPlug allows you to write reusable libraries and applications that need +an HTTP client without binding to a specific implementation. +When all packages used in an application only specify HTTPlug, +the application developers can choose the client that best fits their project +and use the same client with all packages. + +The client interfaces +--------------------- + +HTTPlug defines two HTTP client interfaces that we kept as simple as possible: + +* ``HttpClient`` defines a ``sendRequest`` method that sends a PSR-7 + ``RequestInterface`` and either returns a PSR-7 ``ResponseInterface`` or + throws an exception that implements ``Http\Client\Exception``. + +* ``HttpAsyncClient`` defines a ``sendAsyncRequest`` method that sends a request + asynchronously and always returns a ``Http\Client\Promise``. -HTTPlug implementations typically are either HTTP clients of their own, or adapters wrapping existing clients -like Guzzle 6. In the latter case, they will depend on the required client implementation, -so you only need to require the adapter and not the actual client. +Implementations +--------------- +PHP-HTTP offers two types of clients that implement the above interfaces: -There are two kind of implementations: +1. Standalone clients that directly implement the interfaces. - - `php-http/client-implementation`_: - the synchronous implementation that waits for the response / error before returning from the ``sendRequest`` method. + Examples: :doc:`/clients/curl-client` and :doc:`/clients/socket-client`. - - `php-http/async-client-implementation`_: - the asynchronous implementation that immediately returns a ``Http\Promise\Promise``, - allowing to send several requests in parallel and handling responses later. +2. Adapters that wrap existing HTTP client, such as Guzzle. These adapters act + as a bridge between the HTTPlug interfaces and the clients that do not (yet) + implement these interfaces. -Check links above for the full list of implementations. + Examples: :doc:`/clients/guzzle6-adapter` and :doc:`/clients/react-adapter`. -.. _`php-http/client-implementation`: https://packagist.org/providers/php-http/client-implementation -.. _`php-http/async-client-implementation`: https://packagist.org/providers/php-http/async-client-implementation: +.. note:: + + Ideally, all HTTP client libraries out there will implement the HTTPlug + interfaces. At that point, our adapters will no longer be necessary. Usage in an application ----------------------- -When writing an application, you need to require a concrete implementation_. +When writing an application, you need to require a concrete implementation. See :doc:`virtual-package` for more information on the topic of working with HTTPlug implementations. @@ -69,27 +85,20 @@ Best point them to the :doc:`virtual-package` page. To be able to send requests, you should not depend on a specific PSR-7 implementation, but use the :ref:`message-factory` system. -Framework Integration -^^^^^^^^^^^^^^^^^^^^^ - -HTTPlug can be used in any PHP based project. -Nonetheless, we provide particular integration for some popular frameworks: - -- HttplugBundle_: integration with the Symfony framework. - History ------- -This project has been started by `Eric Geloen`_ as `Ivory Http Adapter`_. It never made it to a stable release, -but it relied on PSR-7 which was not stable either that time. Because of the constantly changing PSR-7, -Eric had to rewrite the library over and over again (at least the message handling part, -which in most cases affected every adapter as well). +This project has been started by `Eric Geloen`_ as `Ivory Http Adapter`_. It +never made it to a stable release, but it relied on PSR-7 which was not stable +either that time. Because of the constantly changing PSR-7, Eric had to rewrite +the library over and over again (at least the message handling part, which in +most cases affected every adapter as well). -In 2015, a decision has been made to move the library to its own organization, so PHP HTTP was born. +In 2015, a decision has been made to move the library to its own organization, +so PHP-HTTP was born. -See :doc:`migrating` for a guide how to migrate your code from the Ivory adapter to HTTPlug. +See :doc:`migrating` for a guide how to migrate your code from the Ivory +adapter. -.. _implementation: https://packagist.org/providers/php-http/client-implementation -.. _HttplugBundle: https://github.com/php-http/HttplugBundle .. _`Eric Geloen`: https://github.com/egeloen -.. _`Ivory Http Adapter`: https://github.com/egeloen/ivory-http-adapter). +.. _`Ivory Http Adapter`: https://github.com/egeloen/ivory-http-adapter diff --git a/httplug/usage.rst b/httplug/usage.rst new file mode 100644 index 0000000..0098995 --- /dev/null +++ b/httplug/usage.rst @@ -0,0 +1,17 @@ +Usage +===== + +HTTPlug is an abstraction for HTTP clients. There are two main use cases: + +1. Usage in a project/application +2. Usage in a reusable package + + +Framework Integration +^^^^^^^^^^^^^^^^^^^^^ + +HTTPlug can be used in any PHP based project. +Nonetheless, we provide particular integration for some popular frameworks: + +- HttplugBundle_: integration with the Symfony framework. + diff --git a/index.rst b/index.rst index 66ab5da..6309fa8 100644 --- a/index.rst +++ b/index.rst @@ -29,17 +29,7 @@ HTTPlug abstracts from HTTP clients written in PHP, offering a simple interface. It also provides an implementation-independent plugin system to build pipelines regardless of the HTTP client implementation used. -HTTPlug allows you to write reusable libraries and applications that need -an HTTP client without binding to a specific implementation. -When all packages used in an application only specify HTTPlug, -the application developers can choose the client that best fits their project -and use the same client with all packages. - -There are clients implementing one of the HTTPlug interfaces directly, -and adapter packages that implement the interface and forward the calls to HTTP -clients not implementing the interface. - -Get started by reading our :doc:`tutorial `. +Read more about :doc:`HTTPlug `. Packages -------- @@ -64,17 +54,19 @@ for discussion around a future HTTP client PSR. .. toctree:: :hidden: - :maxdepth: 3 PHP-HTTP .. toctree:: :hidden: - - HTTPlug - -.. toctree:: - :hidden: + :caption: HTTPlug + :maxdepth: 4 + + Introduction + Usage + Tutorial + Migrating + Virtual package clients plugins/index From b4a7cf3cf5c3b6d19ef975ab09593f2e42aa8fa0 Mon Sep 17 00:00:00 2001 From: David de Boer Date: Sun, 3 Jan 2016 15:47:30 +0100 Subject: [PATCH 2/2] Restructure usage chapters --- clients.rst | 11 +++++ httplug/application-developers.rst | 11 +++++ httplug/introduction.rst | 48 ++----------------- httplug/library-developers.rst | 76 ++++++++++++++++++++++++++++++ httplug/tutorial.rst | 5 -- httplug/usage.rst | 21 ++++----- httplug/users.rst | 56 ++++++++++++++++++++++ httplug/virtual-package.rst | 56 ---------------------- index.rst | 8 ++-- 9 files changed, 172 insertions(+), 120 deletions(-) create mode 100644 httplug/application-developers.rst create mode 100644 httplug/library-developers.rst create mode 100644 httplug/users.rst delete mode 100644 httplug/virtual-package.rst diff --git a/clients.rst b/clients.rst index 5a1efcd..239e843 100644 --- a/clients.rst +++ b/clients.rst @@ -23,3 +23,14 @@ Client adapters: clients/guzzle5-adapter clients/guzzle6-adapter clients/react-adapter + +Composer Virtual Packages +------------------------- + +Virtual packages are a way to specify the dependency on an implementation of an interface-only repository +without forcing a specific implementation. For HTTPlug, the virtual package is called ``php-http/client-implementation``. + +There is no project registered with that name. However, all client implementations including client adapters for +HTTPlug use the ``provide`` section to tell composer that they do provide the client-implementation. + + diff --git a/httplug/application-developers.rst b/httplug/application-developers.rst new file mode 100644 index 0000000..06d4345 --- /dev/null +++ b/httplug/application-developers.rst @@ -0,0 +1,11 @@ +HTTPlug for application developers +================================== + +Framework integration +--------------------- + +HTTPlug can be used in any PHP based project. Nonetheless, we provide +integration for some popular frameworks: + +- HttplugBundle_: integration with the Symfony framework. + diff --git a/httplug/introduction.rst b/httplug/introduction.rst index b954edc..9708fb3 100644 --- a/httplug/introduction.rst +++ b/httplug/introduction.rst @@ -39,51 +39,13 @@ PHP-HTTP offers two types of clients that implement the above interfaces: Ideally, all HTTP client libraries out there will implement the HTTPlug interfaces. At that point, our adapters will no longer be necessary. -Usage in an application ------------------------ +Usage +----- -When writing an application, you need to require a concrete implementation. +There are two main use cases for HTTPlug: -See :doc:`virtual-package` for more information on the topic of working with HTTPlug implementations. - -Installation in a reusable package ----------------------------------- - -In many cases, packages are designed to be reused from the very beginning. -For example, API clients are usually used in other packages/applications, not on their own. - -Reusable packages should **not rely on a concrete implementation** (like Guzzle 6), -but only require any implementation of HTTPlug. HTTPlug uses the concept of virtual packages. -Instead of depending on only the interfaces, which would be missing an implementation, -or depending on one concrete implementation, you should depend on the virtual package ``php-http/client-implementation`` -or ``php-http/async-client-implementation``. There is no package with that name, -but all clients and adapters implementing HTTPlug declare that they provide one of this virtual package or both. - -You need to edit the ``composer.json`` of your package to add the virtual package. -For development (installing the package standalone, running tests), -add a concrete implementation in the ``require-dev`` section to make the project installable: - -.. code-block:: json - - { - "require": { - "php-http/client-implementation": "^1.0" - }, - "require-dev": { - "php-http/guzzle6-adapter": "^1.0" - }, - } - -For extra convenience, you can use the :doc:`/discovery` system to free the user of your -package from having to instantiate the client. -You should however always accept injecting the client instance to allow the user to configure the client as needed. -You can find an example in the :doc:`/discovery` documentation. - -Users of your package will have to select a concrete adapter in their project to make your package installable. -Best point them to the :doc:`virtual-package` page. - -To be able to send requests, you should not depend on a specific PSR-7 implementation, -but use the :ref:`message-factory` system. +* usage in an application that executes HTTP requests (see :doc:`application-developers`). +* usage in a reusable package that executes HTTP requests (see :doc:`library-developers`). History ------- diff --git a/httplug/library-developers.rst b/httplug/library-developers.rst new file mode 100644 index 0000000..fcfbb02 --- /dev/null +++ b/httplug/library-developers.rst @@ -0,0 +1,76 @@ +HTTPlug for library developers +============================== + +If you’re developing a library or framework that performs HTTP requests, you +should not be dependent on concrete HTTP client libraries (such as Guzzle). +Instead, you should only make sure that *some* HTTP client is available. It is +then up to your users to decide which HTTP client they want to include in their +projects. + +Manage dependencies +------------------- + +To depend on *some* HTTP client, specify either +``php-http/client-implementation`` or ``php-http/async-client-implementation`` +in your library’s ``composer.json``. These are virtual Composer packages that +will throw an error if no concrete client was found: + +.. code-block:: json + + { + "name": "you/and-your-awesome-library", + "require": { + "php-http/client-implementation": "^1.0" + } + } + +Your users then include your project alongside with a HTTP client of their +choosing in their project’s ``composer.json``. In this case, the user decided +to include the Socket client: + +.. code-block:: json + + { + "name": "some-user/nice-project", + "require": { + "you/and-your-awesome-library": "^1.2", + "php-http/socket-client": "^1.0" + } + } + +Standalone installation +----------------------- + +This is sufficient for your library’s users. For the library’s developers, +however, it’s best if some specific client is installed when they run +``composer install`` in the library’s directory. So specify any concrete client +in the ``require-dev`` section in your library’s ``composer.json``. In this +example, we chose the Guzzle 6 adapter: + +.. code-block:: json + + { + "name": "you/and-your-awesome-library", + "require": { + "php-http/client-implementation": "^1.0" + }, + "require-dev": { + "php-http/guzzle6-adapter": "^1.0" + } + } + +For extra convenience, you can use :doc:`/discovery` to free your users from +having to instantiate the client. + +Messages +-------- + +When you construct HTTP message objects in your library, you should not depend +on a concrete PSR-7 message implementation. Instead, use the +:ref:`PHP-HTTP message factory `. + +User documentation +------------------ + +To explain to your users that they need to install a concrete HTTP client, +you can point them to :doc:`users`. diff --git a/httplug/tutorial.rst b/httplug/tutorial.rst index ca3afa8..e9acd16 100644 --- a/httplug/tutorial.rst +++ b/httplug/tutorial.rst @@ -155,8 +155,3 @@ Handling errors --------------- TODO: explain how to handle exceptions, distinction between network exception and HttpException. - -Writing a reusable package --------------------------- - -See :ref:`httplug-building-reusable-library` diff --git a/httplug/usage.rst b/httplug/usage.rst index 0098995..1fe3f94 100644 --- a/httplug/usage.rst +++ b/httplug/usage.rst @@ -1,17 +1,12 @@ -Usage -===== +HTTPlug usage +============= -HTTPlug is an abstraction for HTTP clients. There are two main use cases: +HTTPlug is relevant for three groups of users: -1. Usage in a project/application -2. Usage in a reusable package +.. toctree:: + :maxdepth: 1 - -Framework Integration -^^^^^^^^^^^^^^^^^^^^^ - -HTTPlug can be used in any PHP based project. -Nonetheless, we provide particular integration for some popular frameworks: - -- HttplugBundle_: integration with the Symfony framework. + Library users + Application developers + Library developers diff --git a/httplug/users.rst b/httplug/users.rst new file mode 100644 index 0000000..4834cb0 --- /dev/null +++ b/httplug/users.rst @@ -0,0 +1,56 @@ +HTTPlug for library users +========================= + +If you use a library that depends on HTTPlug (say, ``some/awesome-library``), +you need to include an HTTPlug client in your project before you can include +``awesome-library``. + +From the list of :doc:`clients `, choose on that best fits your +application, then include it in your project. For instance, if you decide to +use the Socket client: + +.. code-block:: bash + + $ composer require php-http/socket-client + +Instead of an HTTPlug client, you may want to use an adapter for your favorite +HTTP client. If that turns out to be Guzzle: + +.. code-block:: bash + + $ composer require php-http/guzzle6-adapter + +Then you can include the library: + +.. code-block:: bash + + $ composer require some/awesome-library + +Troubleshooting +--------------- + +If you try to include the HTTPlug-dependent library before you have included a +HTTP client in your project, Composer will throw an error: + +.. code-block:: none + + Loading composer repositories with package information + Updating dependencies (including require-dev) + Your requirements could not be resolved to an installable set of packages. + + Problem 1 + - The requested package php-http/client-implementation could not be found in any version, + there may be a typo in the package name. + +You can solve this by including a HTTP client or adapter, as described above. + +Background +---------- + +Reusable libraries do not depend on a concrete implementation but only on the virtual package +``php-http/client-implementation``. This is to avoid hard coupling and allows the user of the +library to choose the implementation. You can think of this as an "interface" or "contract" for packages. + +When *using a reusable library* in an application, one must ``require`` a concrete implementation. +Make sure the ``require`` section includes a package that provides ``php-http/client-implementation``. +Failing to do that will lead to composer reporting this error: diff --git a/httplug/virtual-package.rst b/httplug/virtual-package.rst deleted file mode 100644 index 89d1362..0000000 --- a/httplug/virtual-package.rst +++ /dev/null @@ -1,56 +0,0 @@ -.. _virtual-package: - -Composer Virtual Packages -========================= - -Virtual packages are a way to specify the dependency on an implementation of an interface-only repository -without forcing a specific implementation. For HTTPlug, the virtual package is called ``php-http/client-implementation``. - -There is no project registered with that name. However, all client implementations including client adapters for -HTTPlug use the ``provide`` section to tell composer that they do provide the client-implementation. - - -Using a Library that depends on HTTPlug ---------------------------------------- - -Reusable libraries do not depend on a concrete implementation but only on the virtual package -``php-http/client-implementation``. This is to avoid hard coupling and allows the user of the -library to choose the implementation. You can think of this as an "interface" or "contract" for packages. - -When *using a reusable library* in an application, one must ``require`` a concrete implementation. -Make sure the ``require`` section includes a package that provides ``php-http/client-implementation``. -Failing to do that will lead to composer reporting this error: - -.. code-block:: bash - - $ composer update - Loading composer repositories with package information - Updating dependencies (including require-dev) - Your requirements could not be resolved to an installable set of packages. - - Problem 1 - - The requested package php-http/client-implementation could not be found in any version, - there may be a typo in the package name. - -Doing something like the following will make this problem go away: - -.. code-block:: bash - - $ composer require php-http/guzzle6-adapter - -Pick a client based on your personal preferences or dependencies of your project. -If your preferred client has no HTTPlug adapter, submit one. - -The client will in turn depend on ``php-http/httplug``, thus you do not need to duplicate the -dependency on ``php-http/httplug`` in your ``composer.json`` file. -However, if your code depends on a minimal version of HTTPlug, -specify it to have composer report problems rather than the application failing at some point. - -.. _httplug-building-reusable-library: - -Building a Reusable Library ---------------------------- - -When *writing a reusable library*, the ``require`` section should only mention ``php-http/client-implementation``, -while the ``require-dev`` section needs to specify a concrete implementation in most cases, -in order for the package to be installable on its own for development and testing. diff --git a/index.rst b/index.rst index 6309fa8..3af11c3 100644 --- a/index.rst +++ b/index.rst @@ -19,8 +19,9 @@ PHP-HTTP has three goals: 2. Provide good quality HTTP-related packages to the PHP community. -3. Over time, make HTTPlug a PSR so that clients will directly implement the - HTTPlug interface and our adapters are no longer needed. +3. Over time, make HTTPlug a PHP Standards Recommendation (PSR) so that clients + will directly implement the HTTPlug interface and our adapters are no longer + needed. HTTPlug ------- @@ -46,6 +47,8 @@ PHP-HTTP offers several packages: | Plugins | Implementation-independent authentication, cookies and more | ``Http\Plugin\[Name]`` | +-----------------+-------------------------------------------------------------+------------------------+ +Read more about :doc:`clients and adapters ` and :doc:`plugins `. + The future ---------- @@ -66,7 +69,6 @@ for discussion around a future HTTP client PSR. Usage Tutorial Migrating - Virtual package clients plugins/index