HTTP client on steroids

It so happens that you don't want to drag a powerful and heavy HTTP client into a project, but you want to take something light, but its functionality is not enough. To deal with these tradeoffs, I have small decorator classes that I have published publicly under the MIT license.

Change of protocol version

HTTP / 2 came to us, but not every server, as well as not every client, supports it. If you try to send a request by forcing the protocol version 2, you may receive an error from the server 505 HTTP Version Not Supported. The webclient / ext-protocol-version package solves this possibly contrived problem. Upon receiving a 505 response, the client will repeat the request, but with the protocol version specified in the server response.

<?php

use Webclient\Extension\ProtocolVersion\Client;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;

/** 
 * @var ClientInterface $client  PSR-18  HTTP Client.
 */
$http = new Client($client);

/** @var RequestInterface $request */
$response = $http->sendRequest($request);

Redirects

It is very rare, but it occurs when the client does not know how to follow redirects when responding with code 3xx. In this case, the webclient / ext-redirect package will help . Everything is elementary here, we pass our client and the maximum number of allowed redirects per request to the constructor.

<?php

use Webclient\Extension\Redirect\Client;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;

/** 
 * @var ClientInterface $client  PSR-18  HTTP Client.
 * @var int $maxRedirects    .
 */
$http = new Client($client, $maxRedirects);

/** @var RequestInterface $request */
$response = $http->sendRequest($request);

Logging

. webclient/ext-log , . , PSR-3 . Webclient\Extension\Log\Formatter\Formatter, ID ( -) - Webclient\Extension\Log\IdGenerator\IdGenerator. :

  • Webclient\Extension\Log\IdGenerator\UniqueIdGenerator - uniqid()

  • Webclient\Extension\Log\Formatter\RawHttpFormatter - RAW-.

<?php

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Webclient\Extension\Log\Client;
use Webclient\Extension\Log\Formatter\Formatter;
use Webclient\Extension\Log\IdGenerator\IdGenerator;

/** 
 * @var ClientInterface $client  PSR-18  HTTP Client.
 * @var LoggerInterface $logger  PSR-3  .
 * @var IdGenerator|null $idGenerator  ID-.
 *        null   
 *      Webclient\Extension\Log\IdGenerator\UniqueIdGenerator.
 * @var Formatter|null $formatter   . 
 *        null   
 *      Webclient\Extension\Log\Formatter\RawHttpFormatter.
 */
$http = new Client(
    $client,
    $logger,
    $idGenerator,
    $formatter,
    LogLevel::INFO, //   
    LogLevel::INFO, //     ( 1xx)
    LogLevel::INFO, //     ( 2xx)
    LogLevel::INFO, //      ( 3xx)
    LogLevel::ERROR, //       ( 4xx)
    LogLevel::ERROR, //       ( 5xx)
    LogLevel::WARNING //    HTTP 
);

/** @var RequestInterface $request */
$response = $http->sendRequest($request);

, . ( -). , Webclient\Extension\Cookie\Cookie\Storage webclient/ext-cookie, :

  • Webclient\Extension\Cookie\Cookie\ArrayStorage - . ;

  • Webclient\Extension\Cookie\Cookie\NetscapeCookieFile - Netscape.

<?php

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Webclient\Extension\Cookie\Client;
use Webclient\Extension\Cookie\Cookie\Storage;

/** 
 * @var ClientInterface $client  PSR-18  HTTP Client.
 * @var Storage $storage  .
 *               .
 */
$http = new Client($client, $storage);

/** @var RequestInterface $request */
$response = $http->sendRequest($request);

, . - ( ), webclient/ext-cache. , Psr\SimpleCache\CacheInterface PSR-6, Psr\Http\Message\ResponseFactoryInterface Psr\Http\Message\StreamFactoryInterface PSR-17.

HTTP- .

<?php

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\SimpleCache\CacheInterface;
use Webclient\Extension\Cache\Client;

/** 
 * @var ClientInterface $client  PSR-18  HTTP Client.
 * @var CacheInterface $cache  PSR-6  .
 * @var ResponseFactoryInterface $responseFactory 
 *       PSR-17   .
 * @var StreamFactoryInterface $streamFactory
 *       PSR-17   .
 * @var string ,     (, ID ).
 */
$http = new Client(
  $client,
  $cache,
  $responseFactory,
  $streamFactory,
  $privateKey
);

/** @var RequestInterface $request */
$response = $http->sendRequest($request);

, . , - .

, PSR-7 - . Psr\Http\Message\RequestInterface (Psr\Http\Message\ServerRequestInterface ). , withUploadedFiles($files) HTTP-. , , . webclient/helper-form . Psr\Http\Message\ResponseFactoryInterface Psr\Http\Message\StreamFactoryInterface.

, (, API), , , .

webclient/fake-http-client, Psr\Http\Client\ClientInterface, Psr\Http\Server\RequestHandlerInterface PSR-15 ( Psr\Http\Message\RequestInterface Psr\Http\Message\ServerRequestInterface). Psr\Http\Server\RequestHandlerInterface - , .

<?php

use Webclient\Fake\Client;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

/** 
 * @var RequestHandlerInterface $handler   . 
 * @var array $serverParams  ,    
 *         Psr\Http\Message\RequestInterface 
 *      Psr\Http\Message\ServerRequestInterface.
 */
$client = new Client($handler, $serverParams);

/**
 * @var RequestInterface $request  HTTP-
 */
$response = $client->sendRequest($request);

Psr\Http\Message\ServerRequestInterface , , Webclient\Fake\Client::NOREPLACEATTRIBUTE ( ).

<?php

use Webclient\Fake\Client;
use Psr\Http\Server\RequestHandlerInterface;

/** 
 * @var Client $client. 
 * @var ServerRequestInterface $request.
 */
$request = $request->withAttribute(Client::NOREPLACEATTRIBUTE, true);
$response = $client->sendRequest($request);

- , Webclient\Fake\Handler\SimpleRoutingHandler - .

<?php

use Webclient\Fake\Client;
use Webclient\Fake\Handler\SimpleRoutingHandler;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

/** 
 * @var RequestHandlerInterface $notFoundHandler  , 
 *          .
 * @var RequestHandlerInterface $entityCreatedHandler  
 *          (POST /entities).
 * @var RequestHandlerInterface $entityHandler  
 *         (GET /entities/1).
 * @var RequestHandlerInterface $entityDeletedHandler  
 *         (DELETE /entities/2).
 * @var RequestInterface $errorRequest   URI (GET /users).
 * @var RequestInterface $entityCreatingRequest   
 *       (POST /entities).
 * @var RequestInterface $entityRequest   
 *       (GET /entities/1).
 * @var RequestInterface $entityDeletingRequest   
 *       (DELETE /entities/2).
 */

$handler = new SimpleRoutingHandler($notFoundHandler);
$handler
    ->route(['GET', 'HEAD'], '/entities/1', $entityHandler)
    ->route(['POST'], '/entities', $entityCreatedHandler)
    ->route(['DELETE'], '/entities/2', $entityDeletedHandler)
;
$client = new Client($handler);

$resp1 = $client->sendRequest($errorRequest); //   404
$resp2 = $client->sendRequest($entityCreatingRequest); //    201
$resp3 = $client->sendRequest($entityRequest); //     200
$resp4 = $client->sendRequest($entityDeletingRequest); //     204

, - . !




All Articles