HTTPlug Tutorial
This tutorial should give you an idea how to use HTTPlug in your project. HTTPlug has two main use cases:
Usage in your project;
Usage in a reusable package.
This tutorial will start with the first use case and then explain the special considerations to take into account when building a reusable package.
We use Composer for dependency management. Install it if you don’t have it yet.
Note
If you are using a framework, check the Framework Integrations to see if there is an integration available. Framework integrations will simplify the way you set up clients, letting you focus on handling the requests.
Setting up the Project
mkdirhttplug-tutorial cdhttplug-tutorial composerinit # specify your information as you want. say no to defining the dependencies interactively composerrequirephp-http/guzzle6-adapter
The last command will install Guzzle as well as the Guzzle HTTPlug adapter and the required interface repositories. We are now ready to start coding.
Writing Some Simple Code
Create a file demo.php in the root folder and write the following code:
<?php require('vendor/autoload.php'); use Http\Discovery\HttpClientDiscovery; use Http\Discovery\MessageFactoryDiscovery; $client = HttpClientDiscovery::find(); $messageFactory = MessageFactoryDiscovery::find(); $homeResponse = $client->sendRequest( $messageFactory->createRequest('GET', 'http://httplug.io') ); var_dump($homeResponse->getStatusCode()); // 200, hopefully $missingPageResponse = $client->sendRequest( $messageFactory->createRequest('GET', 'http://httplug.io/missingPage') ); var_dump($missingPageResponse->getStatusCode()); // 404
Using an Asynchronous Client
Asynchronous client accepts a PSR-7 RequestInterface and returns a Http\Promise\Promise:
use Http\Discovery\HttpAsyncClientDiscovery; $httpAsyncClient = HttpAsyncClientDiscovery::find(); $promise = $httpAsyncClient->sendAsyncRequest($request);
Using the Callback System
The promise allows you to add callbacks for when the response is available or an errors happens by using the then method:
$promise->then(function (ResponseInterface $response) { // onFulfilled callback echo 'The response is available'; return $response; }, function (Exception $e) { // onRejected callback echo 'An error happens'; throw $e; });
This method will return another promise so you can manipulate the response and/or exception and still provide a way to interact with this object for your users:
$promise->then(function (ResponseInterface $response) { // onFulfilled callback echo 'The response is available'; return $response; }, function (Exception $e) { // onRejected callback echo 'An error happens'; throw $e; })->then(function (ResponseInterface $response) { echo 'Response still available'; return $response; }, function (Exception $e) { throw $e });
In order to achieve the chain callback, if you read previous examples carefully,
callbacks provided to the then method must return a PSR-7 ResponseInterface or throw a Http\Client\Exception.
For both of the callbacks, if it returns a PSR-7 ResponseInterface it will call the onFulfilled callback for
the next element in the chain, if it throws a Http\Client\Exception it will call the onRejected callback.
i.e. you can inverse the behavior of a call:
$promise->then(function (ResponseInterface $response) use($request) { // onFulfilled callback echo 'The response is available, but it\'s not ok...'; throw new HttpException('My error message', $request, $response); }, function (Exception $e) { // onRejected callback echo 'An error happens, but it\'s ok...'; return $exception->getResponse(); });
Calling the wait method on the promise will wait for the response or exception to be available and
invoke callback provided in the then method.
Using the promise directly
If you don’t want to use the callback system, you can also get the state of the promise with $promise->getState()
will return of one Promise::PENDING, Promise::FULFILLED or Promise::REJECTED.
Then you can get the response of the promise if it’s in FULFILLED state or trigger the exception of the promise
if it’s in REJECTED state with $promise->wait(true) call.
Note
Read Promise for more information about promises.
Example
Here is a full example of a classic usage when using the sendAsyncRequest method:
use Http\Client\Exception; use Http\Discovery\HttpAsyncClientDiscovery; $httpAsyncClient = HttpAsyncClientDiscovery::find(); $promise = $httpAsyncClient->sendAsyncRequest($request); $promise->then(function (ResponseInterface $response) { echo 'The response is available'; return $response; }, function (Exception $e) { echo 'An error happens'; throw $e; }); // Do some stuff not depending on the response, calling another request, etc .. ... try { // We need now the response for our final treatment... $response = $promise->wait(true); } catch (Exception $e) { // ...or catch the thrown exception } // Do your stuff with the response ...
Handling Errors
TODO: explain how to handle exceptions, distinction between network exception and HttpException.