Completed
Push — master ( 828139...847e66 )
by Rafael
04:50
created

GraphQLEndpointController::__invoke()   C

Complexity

Conditions 13
Paths 121

Size

Total Lines 58
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 27.5142

Importance

Changes 0
Metric Value
dl 0
loc 58
ccs 19
cts 34
cp 0.5588
rs 5.8796
c 0
b 0
f 0
cc 13
eloc 34
nc 121
nop 1
crap 27.5142

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*******************************************************************************
4
 *  This file is part of the GraphQL Bundle package.
5
 *
6
 *  (c) YnloUltratech <[email protected]>
7
 *
8
 *  For the full copyright and license information, please view the LICENSE
9
 *  file that was distributed with this source code.
10
 ******************************************************************************/
11
12
namespace Ynlo\GraphQLBundle\Controller;
13
14
use GraphQL\Error\ClientAware;
15
use GraphQL\Error\Debug;
16
use GraphQL\GraphQL;
17
use GraphQL\Validator\DocumentValidator;
18
use GraphQL\Validator\Rules;
19
use Psr\Log\LoggerInterface;
20
use Symfony\Component\HttpFoundation\JsonResponse;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpFoundation\Response;
23
use Symfony\Component\HttpKernel\Exception\HttpException;
24
use Ynlo\GraphQLBundle\Schema\SchemaCompiler;
25
26
class GraphQLEndpointController
27
{
28
    private $compiler;
29
    private $debug;
30
    private $logger;
31
32 22
    public function __construct(SchemaCompiler $compiler, bool $debug, LoggerInterface $logger = null)
33
    {
34 22
        $this->compiler = $compiler;
35 22
        $this->debug = $debug;
36 22
        $this->logger = $logger;
37 22
    }
38
39 22
    public function __invoke(Request $request): JsonResponse
40
    {
41 22
        if (!$this->debug && $request->getMethod() !== Request::METHOD_POST) {
42
            throw new HttpException(Response::HTTP_BAD_REQUEST, 'The method should be POST to talk with GraphQL API');
43
        }
44
45 22
        $input = json_decode($request->getContent(), true);
46 22
        $query = $input['query'];
47 22
        $context = null;
48 22
        $variableValues = $input['variables'] ?? null;
49 22
        $operationName = $input['operationName'] ?? null;
50
        // this will override global validation rules for this request
51 22
        $validationRules = null;
52
53
        try {
54 22
            $schema = $this->compiler->compile();
55 22
            $schema->assertValid();
56
57 22
            $result = GraphQL::executeQuery($schema, $query, null, $context, $variableValues, $operationName, null, $validationRules);
58
59 22
            if (!$this->debug) {
60
                // in case of debug = false
61
                // If API_DEBUG is passed, output of error formatter is enriched which debugging information.
62
                // Helpful for tests to get full error logs without the need of enable full app debug flag
63 22
                if (isset($_ENV['API_DEBUG'])) {
64
                    $this->debug = $_ENV['API_DEBUG'];
65 22
                } elseif (isset($_SERVER['API_DEBUG'])) {
66
                    $this->debug = $_SERVER['API_DEBUG'];
67
                }
68
            }
69
70 22
            $debugFlags = false;
71 22
            if ($this->debug) {
72
                $debugFlags = Debug::INCLUDE_DEBUG_MESSAGE | Debug::INCLUDE_TRACE;
73
            }
74
75 22
            $output = $result->toArray($debugFlags);
76 22
            $statusCode = Response::HTTP_OK;
77
        } catch (\Exception $e) {
78
            if (null !== $this->logger) {
79
                $this->logger->error($e->getMessage(), $e->getTrace());
80
            }
81
            $statusCode = Response::HTTP_INTERNAL_SERVER_ERROR;
82
            $message = Response::$statusTexts[$statusCode] ?? 'Internal Server Error';
83
84
            if ($this->debug || ($e instanceof ClientAware && $e->isClientSafe())) {
85
                $message = $e->getMessage();
86
            }
87
88
            $output['errors']['message'] = $message;
89
            $output['errors']['category'] = 'internal';
90
91
            if ($this->debug) {
92
                $output['errors']['trace'] = $e->getTraceAsString();
93
            }
94
        }
95
96 22
        return JsonResponse::create($output, $statusCode);
97
    }
98
99 22
    public function addGlobalValidationRules(array $validationRules): void
100
    {
101 22
        $rules = [];
102 22
        if (!empty($validationRules['query_complexity'])) {
103 22
            $rules[] = new Rules\QueryComplexity($validationRules['query_complexity']);
104
        }
105 22
        if (!empty($validationRules['query_depth'])) {
106
            $rules[] = new Rules\QueryDepth($validationRules['query_depth']);
107
        }
108 22
        if (!empty($validationRules['disable_introspection'])) {
109
            $rules[] = new Rules\DisableIntrospection();
110
        }
111 22
        array_map([DocumentValidator::class, 'addRule'], $rules);
112 22
    }
113
}
114