Skip to content

Commit 85494b7

Browse files
committed
Add a config variable to set the HTTP code in the operations
In the default implementation in GraphQLite when an operation result has any error the status code by default is Bad Request (400), this is not the way how GraphQL clients expects a response, with this setter we can set a custom behavior to handle this cases.
1 parent 1bf377a commit 85494b7

File tree

4 files changed

+70
-2
lines changed

4 files changed

+70
-2
lines changed

config/graphqlite.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
use GraphQL\Error\Debug;
4+
use TheCodingMachine\GraphQLite\Http\HttpCodeDecider;
45

56
return [
67
/*
@@ -21,4 +22,7 @@
2122
'debug' => Debug::RETHROW_UNSAFE_EXCEPTIONS,
2223
'uri' => env('GRAPHQLITE_URI', '/graphql'),
2324
'middleware' => ['web'],
25+
26+
// Sets the status code in the HTTP request where operations have errors.
27+
'decider' => HttpCodeDecider::class,
2428
];

src/Controllers/GraphQLiteController.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use GraphQL\Server\StandardServer;
1212
use GraphQL\Upload\UploadMiddleware;
1313
use TheCodingMachine\GraphQLite\Http\HttpCodeDecider;
14+
use TheCodingMachine\GraphQLite\Http\HttpCodeDeciderInterface;
1415
use function array_map;
1516
use function json_decode;
1617
use function json_last_error;
@@ -32,12 +33,15 @@ class GraphQLiteController
3233
private $standardServer;
3334
/** @var bool|int */
3435
private $debug;
36+
/** @var HttpCodeDeciderInterface */
37+
private $codeDecider;
3538

3639
public function __construct(StandardServer $standardServer, HttpMessageFactoryInterface $httpMessageFactory = null, ?int $debug = Debug::RETHROW_UNSAFE_EXCEPTIONS)
3740
{
3841
$this->standardServer = $standardServer;
3942
$this->httpMessageFactory = $httpMessageFactory ?: new DiactorosFactory();
4043
$this->debug = $debug === null ? false : $debug;
44+
$this->codeDecider = new HttpCodeDecider();
4145
}
4246

4347
/**
@@ -71,7 +75,7 @@ private function handlePsr7Request(ServerRequestInterface $request): JsonRespons
7175
{
7276
$result = $this->standardServer->executePsrRequest($request);
7377

74-
$httpCodeDecider = new HttpCodeDecider();
78+
$httpCodeDecider = $this->codeDecider;
7579
if ($result instanceof ExecutionResult) {
7680
return new JsonResponse($result->toArray($this->debug), $httpCodeDecider->decideHttpStatusCode($result));
7781
}
@@ -89,4 +93,9 @@ private function handlePsr7Request(ServerRequestInterface $request): JsonRespons
8993
}
9094
throw new RuntimeException('Unexpected response from StandardServer::executePsrRequest'); // @codeCoverageIgnore
9195
}
96+
97+
public function setCodeDecider(HttpCodeDeciderInterface $decider): void
98+
{
99+
$this->codeDecider = $decider;
100+
}
92101
}

src/Providers/GraphQLiteServiceProvider.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Component\Cache\Psr16Cache;
2020
use TheCodingMachine\GraphQLite\Context\Context;
2121
use TheCodingMachine\GraphQLite\Exceptions\WebonyxErrorHandler;
22+
use TheCodingMachine\GraphQLite\Http\HttpCodeDecider;
2223
use TheCodingMachine\GraphQLite\Laravel\Listeners\CachePurger;
2324
use TheCodingMachine\GraphQLite\Laravel\Mappers\Parameters\ValidateFieldMiddleware;
2425
use TheCodingMachine\GraphQLite\Laravel\Mappers\PaginatorTypeMapper;
@@ -88,8 +89,14 @@ public function register()
8889

8990
$this->app->singleton(GraphQLiteController::class, function (Application $app) {
9091
$debug = config('graphqlite.debug', Debug::RETHROW_UNSAFE_EXCEPTIONS);
92+
$controller = new GraphQLiteController($app[StandardServer::class], $app[HttpMessageFactoryInterface::class], $debug);
93+
$decider = config('graphqlite.decider');
9194

92-
return new GraphQLiteController($app[StandardServer::class], $app[HttpMessageFactoryInterface::class], $debug);
95+
if (!empty($decider)) {
96+
$controller->setCodeDecider($app[$decider]);
97+
}
98+
99+
return $controller;
93100
});
94101

95102
$this->app->singleton(StandardServer::class, static function (Application $app) {

tests/Providers/GraphQLiteServiceProviderTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,20 @@
33
namespace TheCodingMachine\GraphQLite\Laravel\Providers;
44

55

6+
use GraphQL\Error\Debug;
7+
use GraphQL\Executor\ExecutionResult;
8+
use GraphQL\Server\StandardServer;
69
use Orchestra\Testbench\TestCase;
10+
use TheCodingMachine\GraphQLite\Http\HttpCodeDeciderInterface;
711
use TheCodingMachine\GraphQLite\Laravel\Listeners\CachePurger;
812
use TheCodingMachine\GraphQLite\Schema;
913
use TheCodingMachine\TDBM\TDBMService;
1014
use function json_decode;
15+
use Illuminate\Http\Request;
16+
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
17+
use TheCodingMachine\GraphQLite\Laravel\Controllers\GraphQLiteController;
18+
use Symfony\Component\HttpFoundation\Request as SymfonyRequest;
19+
1120

1221
class GraphQLiteServiceProviderTest extends TestCase
1322
{
@@ -171,4 +180,43 @@ public function testCachePurger(): void
171180
$cachePurger->handle();
172181
$this->assertTrue(true);
173182
}
183+
184+
/**
185+
* Asserts that the status code has been taken from the HttpCodeDeciderInterface.
186+
*/
187+
public function testChangeTheCodeDecider()
188+
{
189+
$controller = $this->newGraphQLiteController();
190+
$controller->setCodeDecider($this->newCodeDecider(418));
191+
192+
$response = $controller->index($this->newRequest());
193+
194+
$this->assertEquals(418, $response->getStatusCode());
195+
}
196+
197+
private function newCodeDecider(int $statusCode): HttpCodeDeciderInterface
198+
{
199+
return new class implements HttpCodeDeciderInterface {
200+
public function decideHttpStatusCode(ExecutionResult $result): int
201+
{
202+
return 418;
203+
}
204+
};
205+
}
206+
207+
private function newGraphQLiteController(): GraphQLiteController
208+
{
209+
$server = $this->app->make(StandardServer::class);
210+
$messageFactory = $this->app->make(PsrHttpFactory::class);
211+
return new GraphQLiteController($server, $messageFactory, Debug::RETHROW_UNSAFE_EXCEPTIONS);
212+
}
213+
214+
private function newRequest(): Request
215+
{
216+
$baseRequest = SymfonyRequest::create('https://localhost', 'GET', [
217+
'query' => '{ testValidatorMultiple(foo:"192.168.1.1") }'
218+
]);
219+
220+
return Request::createFromBase($baseRequest);
221+
}
174222
}

0 commit comments

Comments
 (0)