Skip to content

Commit fb486e3

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 738e585 commit fb486e3

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 = DebugFlag::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
/**
@@ -73,7 +77,7 @@ private function handlePsr7Request(ServerRequestInterface $request): JsonRespons
7377
{
7478
$result = $this->standardServer->executePsrRequest($request);
7579

76-
$httpCodeDecider = new HttpCodeDecider();
80+
$httpCodeDecider = $this->codeDecider;
7781
if ($result instanceof ExecutionResult) {
7882
return new JsonResponse($result->toArray($this->debug), $httpCodeDecider->decideHttpStatusCode($result));
7983
}
@@ -91,4 +95,9 @@ private function handlePsr7Request(ServerRequestInterface $request): JsonRespons
9195
}
9296
throw new RuntimeException('Unexpected response from StandardServer::executePsrRequest'); // @codeCoverageIgnore
9397
}
98+
99+
public function setCodeDecider(HttpCodeDeciderInterface $decider): void
100+
{
101+
$this->codeDecider = $decider;
102+
}
94103
}

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', DebugFlag::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)