diff --git a/README.md b/README.md index 509810f..ba55f15 100644 --- a/README.md +++ b/README.md @@ -223,7 +223,9 @@ $gql = $builder->getQuery(); # Constructing The Client A Client object can easily be instantiated by providing the GraphQL endpoint -URL. The Client constructor also receives an optional "authorizationHeaders" +URL. + +The Client constructor also receives an optional "authorizationHeaders" array, which can be used to add authorization headers to all requests being sent to the GraphQL server. @@ -236,6 +238,33 @@ $client = new Client( ); ``` + +The Client constructor also receives an optional "httpOptions" array, which **overrides** the "authorizationHeaders" and can be used to add custom [Guzzle HTTP Client request options](https://guzzle.readthedocs.io/en/latest/request-options.html). + +Example: + +``` +$client = new Client( + 'http://api.graphql.com', + [], + [ + 'connect_timeout' => 5, + 'timeout' => 5, + 'headers' => [ + 'Authorization' => 'Basic xyz' + 'User-Agent' => 'testing/1.0', + ], + 'proxy' => [ + 'http' => 'tcp://localhost:8125', // Use this proxy with "http" + 'https' => 'tcp://localhost:9124', // Use this proxy with "https", + 'no' => ['.mit.edu', 'foo.com'] // Don't use a proxy with these + ], + 'cert' => ['/path/server.pem', 'password'] + ... + ] +); +``` + # Running Queries ## Result Formatting diff --git a/src/Client.php b/src/Client.php index ed519fe..9cd6269 100644 --- a/src/Client.php +++ b/src/Client.php @@ -29,17 +29,25 @@ class Client */ protected $httpClient; + /** + * @var array + */ + protected $httpOptions; + + /** * Client constructor. * * @param string $endpointUrl - * @param array $authorizationHeaders + * @param array $authorizationHeaders + * @param array $httpOptions */ - public function __construct(string $endpointUrl, array $authorizationHeaders = []) + public function __construct(string $endpointUrl, array $authorizationHeaders = [], array $httpOptions = []) { $this->endpointUrl = $endpointUrl; $this->authorizationHeaders = $authorizationHeaders; $this->httpClient = new \GuzzleHttp\Client(); + $this->httpOptions = $httpOptions; } /** @@ -77,6 +85,12 @@ public function runRawQuery(string $queryString, $resultsAsArray = false, array if (!empty($this->authorizationHeaders)) { $options['headers'] = $this->authorizationHeaders; } + + // Set request options for \GuzzleHttp\Client + if (!empty($this->httpOptions)) { + $options = $this->httpOptions; + } + $options['headers']['Content-Type'] = 'application/json'; // Convert empty variables array to empty json object diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 390b1de..b8342dc 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -7,6 +7,7 @@ use GraphQL\QueryBuilder\QueryBuilder; use GraphQL\RawObject; use GuzzleHttp\Exception\ClientException; +use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\ServerException; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; @@ -58,6 +59,7 @@ public function testConstructClient() $mockHandler->append(new Response(200)); $mockHandler->append(new Response(200)); $mockHandler->append(new Response(200)); + $mockHandler->append(new Response(200)); $client = new MockClient('', $handler); $client->runRawQuery('query_string'); @@ -68,13 +70,16 @@ public function testConstructClient() $client = new MockClient('', $handler); $client->runRawQuery('query_string', false, ['name' => 'val']); + $client = new MockClient('', $handler, ['Authorization' => 'Basic xyz'], ['headers' => [ 'Authorization' => 'Basic zyx', 'User-Agent' => 'test' ]]); + $client->runRawQuery('query_string'); + /** @var Request $firstRequest */ $firstRequest = $container[0]['request']; $this->assertEquals('{"query":"query_string","variables":{}}', $firstRequest->getBody()->getContents()); /** @var Request $thirdRequest */ $thirdRequest = $container[1]['request']; - $this->assertNotNull($thirdRequest->getHeader('Authorization')); + $this->assertNotEmpty($thirdRequest->getHeader('Authorization')); $this->assertEquals( ['Basic xyz'], $thirdRequest->getHeader('Authorization') @@ -83,6 +88,13 @@ public function testConstructClient() /** @var Request $secondRequest */ $secondRequest = $container[2]['request']; $this->assertEquals('{"query":"query_string","variables":{"name":"val"}}', $secondRequest->getBody()->getContents()); + + /** @var Request $fourthRequest */ + $fourthRequest = $container[3]['request']; + $this->assertNotEmpty($fourthRequest->getHeader('Authorization')); + $this->assertNotEmpty($fourthRequest->getHeader('User-Agent')); + $this->assertEquals(['Basic zyx'], $fourthRequest->getHeader('Authorization')); + $this->assertEquals(['test'], $fourthRequest->getHeader('User-Agent')); } /** @@ -232,4 +244,14 @@ public function testInternalServerErrorResponse() $this->expectException(ServerException::class); $this->client->runRawQuery(''); } + + /** + * @covers \GraphQL\Client::runRawQuery + */ + public function testConnectTimeoutResponse() + { + $this->mockHandler->append(new ConnectException('Time Out', new Request('post', ''))); + $this->expectException(ConnectException::class); + $this->client->runRawQuery(''); + } } \ No newline at end of file diff --git a/tests/MockClient.php b/tests/MockClient.php index 6d14e9f..c908ec5 100644 --- a/tests/MockClient.php +++ b/tests/MockClient.php @@ -16,11 +16,12 @@ class MockClient extends Client * * @param string $endpointUrl * @param object $handler - * @param array $authorizationHeaders + * @param array $authorizationHeaders + * @param array $httpOptions */ - public function __construct(string $endpointUrl, $handler, array $authorizationHeaders = []) + public function __construct(string $endpointUrl, $handler, array $authorizationHeaders = [], array $httpOptions = []) { - parent::__construct($endpointUrl, $authorizationHeaders); + parent::__construct($endpointUrl, $authorizationHeaders, $httpOptions); $this->httpClient = new \GuzzleHttp\Client(['handler' => $handler]); } } \ No newline at end of file