forked from API-Skeletons/ldog
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGraphQLController.php
More file actions
105 lines (89 loc) · 3.53 KB
/
GraphQLController.php
File metadata and controls
105 lines (89 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
declare(strict_types=1);
namespace App\Http\Controllers;
use ApiSkeletons\Doctrine\ORM\GraphQL\Config;
use ApiSkeletons\Doctrine\ORM\GraphQL\Driver;
use ApiSkeletons\Laravel\ApiProblem\Facades\ApiProblem;
use App\GraphQL\Mutation;
use App\GraphQL\Query;
use Doctrine\Laminas\Hydrator\DoctrineObject;
use Doctrine\ORM\EntityManager;
use GraphQL\Error\DebugFlag;
use GraphQL\Error\Error;
use GraphQL\Error\FormattedError;
use GraphQL\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Schema;
use GraphQL\Validator\DocumentValidator;
use GraphQL\Validator\Rules\QueryComplexity;
use Illuminate\Http\Request;
use function array_map;
use function config;
class GraphQLController extends Controller
{
/** @return mixed[] */
public function __invoke(EntityManager $entityManager, Request $request): array
{
$query = $request->json('query');
$variables = $request->json('variables') ?? [];
$operationName = $request->json('operationName');
if (! $query) {
return ApiProblem::response('Query is required', 422);
}
$context = [];
$driver = new Driver($entityManager, new Config([
'globalByValue' => false,
'entityPrefix' => 'App\\Doctrine\\ORM\\Entity\\',
'groupSuffix' => '',
'limit' => 100,
'sortFields' => true,
'useHydratorCache' => true,
]));
// Because a hydrator is used in the mutation, set it in the Driver
// container for easy access.
$driver->set(DoctrineObject::class, new DoctrineObject($entityManager, false));
$schema = new Schema([
'query' => new ObjectType([
'name' => 'query',
'fields' => [
'artist' => Query\Artist\Entity::getDefinition($driver, $variables, $operationName),
'artists' => Query\Artist\Connection::getDefinition($driver, $variables, $operationName),
'performances' => Query\Performance\Connection::getDefinition($driver, $variables, $operationName),
],
]),
'mutation' => new ObjectType([
'name' => 'mutation',
'fields' => [
'artistCreate' => Mutation\Artist\Create::getDefinition($driver, $variables, $operationName),
],
]),
]);
// Limit query complexity
DocumentValidator::addRule(new QueryComplexity(350));
// Disable introspection in production
/*
use GraphQL\Validator\Rules\DisableIntrospection;
if (! config('app.debug')) {
$rule = new DisableIntrospection(DisableIntrospection::ENABLED);
DocumentValidator::addRule($rule);
}
*/
// Execute
$result = GraphQL::executeQuery(
schema: $schema,
source: (string) $query,
contextValue: $context,
variableValues: $variables,
operationName: $operationName,
)
->setErrorFormatter(static function (Error $error): array {
return FormattedError::createFromException($error);
})
->setErrorsHandler(static fn (array $errors, callable $formatter): array => array_map($formatter, $errors));
// Show debug output if under development; else none
$debugFlag = config('app.debug') ?
DebugFlag::INCLUDE_DEBUG_MESSAGE | DebugFlag::INCLUDE_TRACE
: DebugFlag::NONE;
return $result->toArray($debugFlag);
}
}