diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cbc9e0..f115d39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - RetryPlugin will no longer retry requests when the response failed with a HTTP code < 500. - Abstract method `HttpClientPool::chooseHttpClient()` has now an explicit return type (`Http\Client\Common\HttpClientPoolItem`) - Interface method `Plugin::handleRequest(...)` has now an explicit return type (`Http\Promise\Promise`) +- Made classes final that are not intended to be extended. + Added interfaces for BatchClient, HttpClientRouter and HttpMethodsClient. + (These interfaces use the `Interface` suffix to avoid name collisions.) +- Added an interface for HttpClientPool and moved the abstract class to the HttpClientPool sub namespace. ### Removed - Deprecated option `debug_plugins` has been removed from `PluginClient` diff --git a/spec/HttpClientPoolItemSpec.php b/spec/HttpClientPool/HttpClientPoolItemSpec.php similarity index 99% rename from spec/HttpClientPoolItemSpec.php rename to spec/HttpClientPool/HttpClientPoolItemSpec.php index f44351b..22c0b7d 100644 --- a/spec/HttpClientPoolItemSpec.php +++ b/spec/HttpClientPool/HttpClientPoolItemSpec.php @@ -1,6 +1,6 @@ shouldHaveType(HttpClientRouter::class); } + public function it_is_an_http_client_router() + { + $this->shouldImplement(HttpClientRouterInterface::class); + } + public function it_is_an_http_client() { $this->shouldImplement(HttpClient::class); diff --git a/spec/HttpMethodsClientSpec.php b/spec/HttpMethodsClientSpec.php index 74e0810..68e124d 100644 --- a/spec/HttpMethodsClientSpec.php +++ b/spec/HttpMethodsClientSpec.php @@ -2,135 +2,88 @@ namespace spec\Http\Client\Common; -use GuzzleHttp\Psr7\Response; use Http\Client\Common\HttpMethodsClient; use Http\Client\HttpClient; -use Http\Message\MessageFactory; +use Http\Message\RequestFactory; use PhpSpec\ObjectBehavior; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; class HttpMethodsClientSpec extends ObjectBehavior { - public function let(HttpClient $client, MessageFactory $messageFactory) + private static $requestData = [ + 'uri' => '/uri', + 'headers' => [ + 'Content-Type' => 'text/plain', + ], + 'body' => 'body', + ]; + + public function let(HttpClient $client, RequestFactory $requestFactory) { $this->beAnInstanceOf( - HttpMethodsClientStub::class, [ + HttpMethodsClient::class, [ $client, - $messageFactory, + $requestFactory, ] ); } - public function it_sends_a_get_request() + public function it_sends_a_get_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response) { - $data = HttpMethodsClientStub::$requestData; - - $this->get($data['uri'], $data['headers'])->shouldReturnAnInstanceOf(ResponseInterface::class); + $this->assert($client, $requestFactory, $request, $response, 'get'); } - public function it_sends_a_head_request() + public function it_sends_a_head_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response) { - $data = HttpMethodsClientStub::$requestData; - - $this->head($data['uri'], $data['headers'])->shouldReturnAnInstanceOf(ResponseInterface::class); + $this->assert($client, $requestFactory, $request, $response, 'head'); } - public function it_sends_a_trace_request() + public function it_sends_a_trace_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response) { - $data = HttpMethodsClientStub::$requestData; - - $this->trace($data['uri'], $data['headers'])->shouldReturnAnInstanceOf(ResponseInterface::class); + $this->assert($client, $requestFactory, $request, $response, 'trace'); } - public function it_sends_a_post_request() + public function it_sends_a_post_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response) { - $data = HttpMethodsClientStub::$requestData; - - $this->post($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class); + $this->assert($client, $requestFactory, $request, $response, 'post', self::$requestData['body']); } - public function it_sends_a_put_request() + public function it_sends_a_put_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response) { - $data = HttpMethodsClientStub::$requestData; - - $this->put($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class); + $this->assert($client, $requestFactory, $request, $response, 'put', self::$requestData['body']); } - public function it_sends_a_patch_request() + public function it_sends_a_patch_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response) { - $data = HttpMethodsClientStub::$requestData; - - $this->patch($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class); + $this->assert($client, $requestFactory, $request, $response, 'patch', self::$requestData['body']); } - public function it_sends_a_delete_request() + public function it_sends_a_delete_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response) { - $data = HttpMethodsClientStub::$requestData; - - $this->delete($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class); + $this->assert($client, $requestFactory, $request, $response, 'delete', self::$requestData['body']); } - public function it_sends_a_options_request() + public function it_sends_an_options_request(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response) { - $data = HttpMethodsClientStub::$requestData; - - $this->options($data['uri'], $data['headers'], $data['body'])->shouldReturnAnInstanceOf(ResponseInterface::class); + $this->assert($client, $requestFactory, $request, $response, 'options', self::$requestData['body']); } - public function it_sends_request_with_underlying_client(HttpClient $client, MessageFactory $messageFactory, RequestInterface $request, ResponseInterface $response) + /** + * Run the actual test. + * + * As there is no data provider in phpspec, we keep separate methods to get new mocks for each test. + */ + private function assert(HttpClient $client, RequestFactory $requestFactory, RequestInterface $request, ResponseInterface $response, string $method, string $body = null) { $client->sendRequest($request)->shouldBeCalled()->willReturn($response); + $this->mockFactory($requestFactory, $request, strtoupper($method), $body); - $this->beConstructedWith($client, $messageFactory); - $this->sendRequest($request)->shouldReturn($response); + $this->$method(self::$requestData['uri'], self::$requestData['headers'], self::$requestData['body'])->shouldReturnAnInstanceOf(ResponseInterface::class); } -} - -class HttpMethodsClientStub extends HttpMethodsClient -{ - public static $requestData = [ - 'uri' => '/uri', - 'headers' => [ - 'Content-Type' => 'text/plain', - ], - 'body' => 'body', - ]; - /** - * {@inheritdoc} - */ - public function send($method, $uri, array $headers = [], $body = null): ResponseInterface + private function mockFactory(RequestFactory $requestFactory, RequestInterface $request, string $method, string $body = null) { - if ($uri !== self::$requestData['uri']) { - throw new \InvalidArgumentException('Invalid URI: '.$uri); - } - - if ($headers !== self::$requestData['headers']) { - throw new \InvalidArgumentException('Invalid headers: '.print_r($headers, true)); - } - - switch ($method) { - case 'GET': - case 'HEAD': - case 'TRACE': - if (null !== $body) { - throw new \InvalidArgumentException('Non-empty body'); - } - - return new Response(); - case 'POST': - case 'PUT': - case 'PATCH': - case 'DELETE': - case 'OPTIONS': - if ($body !== self::$requestData['body']) { - throw new \InvalidArgumentException('Invalid body: '.print_r($body, true)); - } - - return new Response(); - default: - throw new \InvalidArgumentException('Invalid method: '.$method); - } + $requestFactory->createRequest($method, self::$requestData['uri'], self::$requestData['headers'], $body)->willReturn($request); } } diff --git a/spec/Plugin/AddPathPluginSpec.php b/spec/Plugin/AddPathPluginSpec.php index 414fa04..6491069 100644 --- a/spec/Plugin/AddPathPluginSpec.php +++ b/spec/Plugin/AddPathPluginSpec.php @@ -46,7 +46,7 @@ public function it_adds_path( $this->handleRequest($request, PluginStub::next(), function () {}); } - function it_removes_ending_slashes( + public function it_removes_ending_slashes( RequestInterface $request, UriInterface $host, UriInterface $host2, diff --git a/src/BatchClient.php b/src/BatchClient.php index 8dfeb81..09a83ff 100644 --- a/src/BatchClient.php +++ b/src/BatchClient.php @@ -8,14 +8,7 @@ use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -/** - * BatchClient allow to sends multiple request and retrieve a Batch Result. - * - * This implementation simply loops over the requests and uses sendRequest with each of them. - * - * @author Joel Wurtz - */ -class BatchClient implements HttpClient +final class BatchClient implements BatchClientInterface { /** * @var HttpClient @@ -27,28 +20,11 @@ public function __construct(HttpClient $client) $this->client = $client; } - /** - * {@inheritdoc} - */ public function sendRequest(RequestInterface $request): ResponseInterface { return $this->client->sendRequest($request); } - /** - * Send several requests. - * - * You may not assume that the requests are executed in a particular order. If the order matters - * for your application, use sendRequest sequentially. - * - * @param RequestInterface[] The requests to send - * - * @return BatchResult Containing one result per request - * - * @throws BatchException If one or more requests fails. The exception gives access to the - * BatchResult with a map of request to result for success, request to - * exception for failures - */ public function sendRequests(array $requests): BatchResult { $batchResult = new BatchResult(); diff --git a/src/BatchClientInterface.php b/src/BatchClientInterface.php new file mode 100644 index 0000000..ce6c3c7 --- /dev/null +++ b/src/BatchClientInterface.php @@ -0,0 +1,34 @@ + + */ +interface BatchClientInterface extends HttpClient +{ + /** + * Send several requests. + * + * You may not assume that the requests are executed in a particular order. If the order matters + * for your application, use sendRequest sequentially. + * + * @param RequestInterface[] The requests to send + * + * @return BatchResult Containing one result per request + * + * @throws BatchException If one or more requests fails. The exception gives access to the + * BatchResult with a map of request to result for success, request to + * exception for failures + */ + public function sendRequests(array $requests): BatchResult; +} diff --git a/src/Deferred.php b/src/Deferred.php index 7413451..c294a8d 100644 --- a/src/Deferred.php +++ b/src/Deferred.php @@ -9,7 +9,7 @@ /** * A deferred allow to return a promise which has not been resolved yet. */ -class Deferred implements Promise +final class Deferred implements Promise { private $value; diff --git a/src/EmulatedHttpAsyncClient.php b/src/EmulatedHttpAsyncClient.php index 64acd59..9d6c557 100644 --- a/src/EmulatedHttpAsyncClient.php +++ b/src/EmulatedHttpAsyncClient.php @@ -6,13 +6,11 @@ use Http\Client\HttpClient; /** - * Emulates an async HTTP client. - * - * This should be replaced by an anonymous class in PHP 7. + * Emulates an async HTTP client with the help of a synchronous client. * * @author Márk Sági-Kazár */ -class EmulatedHttpAsyncClient implements HttpClient, HttpAsyncClient +final class EmulatedHttpAsyncClient implements HttpClient, HttpAsyncClient { use HttpAsyncClientEmulator; use HttpClientDecorator; diff --git a/src/EmulatedHttpClient.php b/src/EmulatedHttpClient.php index 3635e9f..d99b4e4 100644 --- a/src/EmulatedHttpClient.php +++ b/src/EmulatedHttpClient.php @@ -6,13 +6,11 @@ use Http\Client\HttpClient; /** - * Emulates an HTTP client. - * - * This should be replaced by an anonymous class in PHP 7. + * Emulates a synchronous HTTP client with the help of an asynchronous client. * * @author Márk Sági-Kazár */ -class EmulatedHttpClient implements HttpClient, HttpAsyncClient +final class EmulatedHttpClient implements HttpClient, HttpAsyncClient { use HttpAsyncClientDecorator; use HttpClientEmulator; diff --git a/src/HttpClientPool.php b/src/HttpClientPool.php index 90a8464..a730f50 100644 --- a/src/HttpClientPool.php +++ b/src/HttpClientPool.php @@ -2,59 +2,20 @@ namespace Http\Client\Common; -use Http\Client\Common\Exception\HttpClientNotFoundException; +use Http\Client\Common\HttpClientPool\HttpClientPoolItem; use Http\Client\HttpAsyncClient; use Http\Client\HttpClient; -use Psr\Http\Message\RequestInterface; -use Psr\Http\Message\ResponseInterface; /** * A http client pool allows to send requests on a pool of different http client using a specific strategy (least used, * round robin, ...). */ -abstract class HttpClientPool implements HttpAsyncClient, HttpClient +interface HttpClientPool extends HttpAsyncClient, HttpClient { - /** - * @var HttpClientPoolItem[] - */ - protected $clientPool = []; - /** * Add a client to the pool. * * @param HttpClient|HttpAsyncClient|HttpClientPoolItem $client */ - public function addHttpClient($client) - { - if (!$client instanceof HttpClientPoolItem) { - $client = new HttpClientPoolItem($client); - } - - $this->clientPool[] = $client; - } - - /** - * Return an http client given a specific strategy. - * - * @throws HttpClientNotFoundException When no http client has been found into the pool - * - * @return HttpClientPoolItem Return a http client that can do both sync or async - */ - abstract protected function chooseHttpClient(): HttpClientPoolItem; - - /** - * {@inheritdoc} - */ - public function sendAsyncRequest(RequestInterface $request) - { - return $this->chooseHttpClient()->sendAsyncRequest($request); - } - - /** - * {@inheritdoc} - */ - public function sendRequest(RequestInterface $request): ResponseInterface - { - return $this->chooseHttpClient()->sendRequest($request); - } + public function addHttpClient($client); } diff --git a/src/HttpClientPool/HttpClientPool.php b/src/HttpClientPool/HttpClientPool.php new file mode 100644 index 0000000..cbac805 --- /dev/null +++ b/src/HttpClientPool/HttpClientPool.php @@ -0,0 +1,61 @@ +clientPool[] = $client; + } + + /** + * Return an http client given a specific strategy. + * + * @throws HttpClientNotFoundException When no http client has been found into the pool + * + * @return HttpClientPoolItem Return a http client that can do both sync or async + */ + abstract protected function chooseHttpClient(): HttpClientPoolItem; + + /** + * {@inheritdoc} + */ + public function sendAsyncRequest(RequestInterface $request) + { + return $this->chooseHttpClient()->sendAsyncRequest($request); + } + + /** + * {@inheritdoc} + */ + public function sendRequest(RequestInterface $request): ResponseInterface + { + return $this->chooseHttpClient()->sendRequest($request); + } +} diff --git a/src/HttpClientPoolItem.php b/src/HttpClientPool/HttpClientPoolItem.php similarity index 73% rename from src/HttpClientPoolItem.php rename to src/HttpClientPool/HttpClientPoolItem.php index a46ee2f..4094502 100644 --- a/src/HttpClientPoolItem.php +++ b/src/HttpClientPool/HttpClientPoolItem.php @@ -1,7 +1,8 @@ */ @@ -29,7 +37,11 @@ class HttpClientPoolItem implements HttpClient, HttpAsyncClient private $disabledAt; /** - * @var int|null Number of seconds after this client is reenable, by default null: never reenable this client + * Number of seconds until this client is enabled again after an error. + * + * null: never reenable this client. + * + * @var int|null */ private $reenableAfter; @@ -40,7 +52,7 @@ class HttpClientPoolItem implements HttpClient, HttpAsyncClient /** * @param HttpClient|HttpAsyncClient $client - * @param null|int $reenableAfter Number of seconds after this client is reenable + * @param null|int $reenableAfter Number of seconds until this client is enabled again after an error */ public function __construct($client, $reenableAfter = null) { @@ -97,21 +109,16 @@ public function sendAsyncRequest(RequestInterface $request) /** * Whether this client is disabled or not. * - * Will also reactivate this client if possible - * - * @internal - * - * @return bool + * If the client was disabled, calling this method checks if the client can + * be reenabled and if so enables it. */ - public function isDisabled() + public function isDisabled(): bool { - $disabledAt = $this->getDisabledAt(); - - if (null !== $this->reenableAfter && null !== $disabledAt) { + if (null !== $this->reenableAfter && null !== $this->disabledAt) { // Reenable after a certain time $now = new \DateTime(); - if (($now->getTimestamp() - $disabledAt->getTimestamp()) >= $this->reenableAfter) { + if (($now->getTimestamp() - $this->disabledAt->getTimestamp()) >= $this->reenableAfter) { $this->enable(); return false; @@ -120,31 +127,17 @@ public function isDisabled() return true; } - return null !== $disabledAt; + return null !== $this->disabledAt; } /** - * Get current number of request that is send by the underlying http client. - * - * @internal - * - * @return int + * Get current number of request that are currently being sent by the underlying HTTP client. */ - public function getSendingRequestCount() + public function getSendingRequestCount(): int { return $this->sendingRequestCount; } - /** - * Return when this client has been disabled or null if it's enabled. - * - * @return \DateTime|null - */ - private function getDisabledAt() - { - return $this->disabledAt; - } - /** * Increment the request count. */ diff --git a/src/HttpClientPool/LeastUsedClientPool.php b/src/HttpClientPool/LeastUsedClientPool.php index 61eb670..e3c29b7 100644 --- a/src/HttpClientPool/LeastUsedClientPool.php +++ b/src/HttpClientPool/LeastUsedClientPool.php @@ -3,8 +3,6 @@ namespace Http\Client\Common\HttpClientPool; use Http\Client\Common\Exception\HttpClientNotFoundException; -use Http\Client\Common\HttpClientPool; -use Http\Client\Common\HttpClientPoolItem; /** * LeastUsedClientPool will choose the client with the less current request in the pool. diff --git a/src/HttpClientPool/RandomClientPool.php b/src/HttpClientPool/RandomClientPool.php index 2889ed7..3adf5fd 100644 --- a/src/HttpClientPool/RandomClientPool.php +++ b/src/HttpClientPool/RandomClientPool.php @@ -3,8 +3,6 @@ namespace Http\Client\Common\HttpClientPool; use Http\Client\Common\Exception\HttpClientNotFoundException; -use Http\Client\Common\HttpClientPool; -use Http\Client\Common\HttpClientPoolItem; /** * RoundRobinClientPool will choose the next client in the pool. diff --git a/src/HttpClientPool/RoundRobinClientPool.php b/src/HttpClientPool/RoundRobinClientPool.php index 3315b51..13cdf13 100644 --- a/src/HttpClientPool/RoundRobinClientPool.php +++ b/src/HttpClientPool/RoundRobinClientPool.php @@ -3,8 +3,6 @@ namespace Http\Client\Common\HttpClientPool; use Http\Client\Common\Exception\HttpClientNotFoundException; -use Http\Client\Common\HttpClientPool; -use Http\Client\Common\HttpClientPoolItem; /** * RoundRobinClientPool will choose the next client in the pool. diff --git a/src/HttpClientRouter.php b/src/HttpClientRouter.php index 00ca15f..56be0bf 100644 --- a/src/HttpClientRouter.php +++ b/src/HttpClientRouter.php @@ -10,11 +10,11 @@ use Psr\Http\Message\ResponseInterface; /** - * Route a request to a specific client in the stack based using a RequestMatcher. + * {@inheritdoc} * * @author Joel Wurtz */ -final class HttpClientRouter implements HttpClient, HttpAsyncClient +final class HttpClientRouter implements HttpClientRouterInterface { /** * @var array @@ -26,9 +26,7 @@ final class HttpClientRouter implements HttpClient, HttpAsyncClient */ public function sendRequest(RequestInterface $request): ResponseInterface { - $client = $this->chooseHttpClient($request); - - return $client->sendRequest($request); + return $this->chooseHttpClient($request)->sendRequest($request); } /** @@ -36,9 +34,7 @@ public function sendRequest(RequestInterface $request): ResponseInterface */ public function sendAsyncRequest(RequestInterface $request) { - $client = $this->chooseHttpClient($request); - - return $client->sendAsyncRequest($request); + return $this->chooseHttpClient($request)->sendAsyncRequest($request); } /** diff --git a/src/HttpClientRouterInterface.php b/src/HttpClientRouterInterface.php new file mode 100644 index 0000000..67fb822 --- /dev/null +++ b/src/HttpClientRouterInterface.php @@ -0,0 +1,24 @@ + + */ +interface HttpClientRouterInterface extends HttpClient, HttpAsyncClient +{ + /** + * Add a client to the router. + * + * @param HttpClient|HttpAsyncClient $client + */ + public function addClient($client, RequestMatcher $requestMatcher); +} diff --git a/src/HttpMethodsClient.php b/src/HttpMethodsClient.php index bc02ef8..69e4df9 100644 --- a/src/HttpMethodsClient.php +++ b/src/HttpMethodsClient.php @@ -2,29 +2,12 @@ namespace Http\Client\Common; -use Http\Client\Exception; use Http\Client\HttpClient; use Http\Message\RequestFactory; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\StreamInterface; -use Psr\Http\Message\UriInterface; -/** - * Convenience HTTP client that integrates the MessageFactory in order to send - * requests in the following form:. - * - * $client - * ->get('/foo') - * ->post('/bar') - * ; - * - * The client also exposes the sendRequest methods of the wrapped HttpClient. - * - * @author Márk Sági-Kazár - * @author David Buchmann - */ -class HttpMethodsClient implements HttpClient +final class HttpMethodsClient implements HttpMethodsClientInterface { /** * @var HttpClient @@ -46,116 +29,46 @@ public function __construct(HttpClient $httpClient, RequestFactory $requestFacto $this->requestFactory = $requestFactory; } - /** - * Sends a GET request. - * - * @param string|UriInterface $uri - * - * @throws Exception - */ public function get($uri, array $headers = []): ResponseInterface { return $this->send('GET', $uri, $headers, null); } - /** - * Sends an HEAD request. - * - * @param string|UriInterface $uri - * - * @throws Exception - */ public function head($uri, array $headers = []): ResponseInterface { return $this->send('HEAD', $uri, $headers, null); } - /** - * Sends a TRACE request. - * - * @param string|UriInterface $uri - * - * @throws Exception - */ public function trace($uri, array $headers = []): ResponseInterface { return $this->send('TRACE', $uri, $headers, null); } - /** - * Sends a POST request. - * - * @param string|UriInterface $uri - * @param string|StreamInterface|null $body - * - * @throws Exception - */ public function post($uri, array $headers = [], $body = null): ResponseInterface { return $this->send('POST', $uri, $headers, $body); } - /** - * Sends a PUT request. - * - * @param string|UriInterface $uri - * @param string|StreamInterface|null $body - * - * @throws Exception - */ public function put($uri, array $headers = [], $body = null): ResponseInterface { return $this->send('PUT', $uri, $headers, $body); } - /** - * Sends a PATCH request. - * - * @param string|UriInterface $uri - * @param string|StreamInterface|null $body - * - * @throws Exception - */ public function patch($uri, array $headers = [], $body = null): ResponseInterface { return $this->send('PATCH', $uri, $headers, $body); } - /** - * Sends a DELETE request. - * - * @param string|UriInterface $uri - * @param string|StreamInterface|null $body - * - * @throws Exception - */ public function delete($uri, array $headers = [], $body = null): ResponseInterface { return $this->send('DELETE', $uri, $headers, $body); } - /** - * Sends an OPTIONS request. - * - * @param string|UriInterface $uri - * @param string|StreamInterface|null $body - * - * @throws Exception - */ public function options($uri, array $headers = [], $body = null): ResponseInterface { return $this->send('OPTIONS', $uri, $headers, $body); } - /** - * Sends a request with any HTTP method. - * - * @param string $method HTTP method to use - * @param string|UriInterface $uri - * @param string|StreamInterface|null $body - * - * @throws Exception - */ public function send($method, $uri, array $headers = [], $body = null): ResponseInterface { return $this->sendRequest($this->requestFactory->createRequest( @@ -166,11 +79,6 @@ public function send($method, $uri, array $headers = [], $body = null): Response )); } - /** - * Forward to the underlying HttpClient. - * - * {@inheritdoc} - */ public function sendRequest(RequestInterface $request): ResponseInterface { return $this->httpClient->sendRequest($request); diff --git a/src/HttpMethodsClientInterface.php b/src/HttpMethodsClientInterface.php new file mode 100644 index 0000000..6bc409f --- /dev/null +++ b/src/HttpMethodsClientInterface.php @@ -0,0 +1,114 @@ +get('/foo') + * ->post('/bar') + * ; + * + * The client also exposes the sendRequest methods of the wrapped HttpClient. + * + * @author Márk Sági-Kazár + * @author David Buchmann + */ +interface HttpMethodsClientInterface extends HttpClient +{ + /** + * Sends a GET request. + * + * @param string|UriInterface $uri + * + * @throws Exception + */ + public function get($uri, array $headers = []): ResponseInterface; + + /** + * Sends an HEAD request. + * + * @param string|UriInterface $uri + * + * @throws Exception + */ + public function head($uri, array $headers = []): ResponseInterface; + + /** + * Sends a TRACE request. + * + * @param string|UriInterface $uri + * + * @throws Exception + */ + public function trace($uri, array $headers = []): ResponseInterface; + + /** + * Sends a POST request. + * + * @param string|UriInterface $uri + * @param string|StreamInterface|null $body + * + * @throws Exception + */ + public function post($uri, array $headers = [], $body = null): ResponseInterface; + + /** + * Sends a PUT request. + * + * @param string|UriInterface $uri + * @param string|StreamInterface|null $body + * + * @throws Exception + */ + public function put($uri, array $headers = [], $body = null): ResponseInterface; + + /** + * Sends a PATCH request. + * + * @param string|UriInterface $uri + * @param string|StreamInterface|null $body + * + * @throws Exception + */ + public function patch($uri, array $headers = [], $body = null): ResponseInterface; + + /** + * Sends a DELETE request. + * + * @param string|UriInterface $uri + * @param string|StreamInterface|null $body + * + * @throws Exception + */ + public function delete($uri, array $headers = [], $body = null): ResponseInterface; + + /** + * Sends an OPTIONS request. + * + * @param string|UriInterface $uri + * @param string|StreamInterface|null $body + * + * @throws Exception + */ + public function options($uri, array $headers = [], $body = null): ResponseInterface; + + /** + * Sends a request with any HTTP method. + * + * @param string $method HTTP method to use + * @param string|UriInterface $uri + * @param string|StreamInterface|null $body + * + * @throws Exception + */ + public function send($method, $uri, array $headers = [], $body = null): ResponseInterface; +}