vendor/overblog/graphql-bundle/src/Controller/GraphController.php line 59

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace Overblog\GraphQLBundle\Controller;
  4. use Overblog\GraphQLBundle\Request as GraphQLRequest;
  5. use Symfony\Component\HttpFoundation\JsonResponse;
  6. use Symfony\Component\HttpFoundation\Request;
  7. use Symfony\Component\HttpFoundation\Response;
  8. class GraphController
  9. {
  10. /**
  11. * @var GraphQLRequest\BatchParser
  12. */
  13. private $batchParser;
  14. /**
  15. * @var GraphQLRequest\Executor
  16. */
  17. private $requestExecutor;
  18. /**
  19. * @var GraphQLRequest\Parser
  20. */
  21. private $requestParser;
  22. /**
  23. * @var bool
  24. */
  25. private $shouldHandleCORS;
  26. /**
  27. * @var bool
  28. */
  29. private $useApolloBatchingMethod;
  30. public function __construct(
  31. GraphQLRequest\ParserInterface $batchParser,
  32. GraphQLRequest\Executor $requestExecutor,
  33. GraphQLRequest\ParserInterface $requestParser,
  34. $shouldHandleCORS,
  35. $graphQLBatchingMethod
  36. ) {
  37. $this->batchParser = $batchParser;
  38. $this->requestExecutor = $requestExecutor;
  39. $this->requestParser = $requestParser;
  40. $this->shouldHandleCORS = $shouldHandleCORS;
  41. $this->useApolloBatchingMethod = 'apollo' === $graphQLBatchingMethod;
  42. }
  43. /**
  44. * @param Request $request
  45. * @param string|null $schemaName
  46. *
  47. * @return JsonResponse|Response
  48. */
  49. public function endpointAction(Request $request, string $schemaName = null)
  50. {
  51. return $this->createResponse($request, $schemaName, false);
  52. }
  53. /**
  54. * @param Request $request
  55. * @param string|null $schemaName
  56. *
  57. * @return JsonResponse|Response
  58. */
  59. public function batchEndpointAction(Request $request, string $schemaName = null)
  60. {
  61. return $this->createResponse($request, $schemaName, true);
  62. }
  63. /**
  64. * @param Request $request
  65. * @param string|null $schemaName
  66. * @param bool $batched
  67. *
  68. * @return JsonResponse|Response
  69. */
  70. private function createResponse(Request $request, string $schemaName = null, bool $batched)
  71. {
  72. if ('OPTIONS' === $request->getMethod()) {
  73. $response = new JsonResponse([], 200);
  74. } else {
  75. if (!\in_array($request->getMethod(), ['POST', 'GET'])) {
  76. return new Response('', 405);
  77. }
  78. $payload = $this->processQuery($request, $schemaName, $batched);
  79. $response = new JsonResponse($payload, 200);
  80. }
  81. $this->addCORSHeadersIfNeeded($response, $request);
  82. return $response;
  83. }
  84. private function addCORSHeadersIfNeeded(Response $response, Request $request): void
  85. {
  86. if ($this->shouldHandleCORS && $request->headers->has('Origin')) {
  87. $response->headers->set('Access-Control-Allow-Origin', $request->headers->get('Origin'), true);
  88. $response->headers->set('Access-Control-Allow-Credentials', 'true', true);
  89. $response->headers->set('Access-Control-Allow-Headers', 'Content-Type, Authorization', true);
  90. $response->headers->set('Access-Control-Allow-Methods', 'OPTIONS, GET, POST', true);
  91. $response->headers->set('Access-Control-Max-Age', '3600', true);
  92. }
  93. }
  94. /**
  95. * @param Request $request
  96. * @param string|null $schemaName
  97. * @param bool $batched
  98. *
  99. * @return array
  100. */
  101. private function processQuery(Request $request, string $schemaName = null, bool $batched): array
  102. {
  103. if ($batched) {
  104. $payload = $this->processBatchQuery($request, $schemaName);
  105. } else {
  106. $payload = $this->processNormalQuery($request, $schemaName);
  107. }
  108. return $payload;
  109. }
  110. /**
  111. * @param Request $request
  112. * @param string|null $schemaName
  113. *
  114. * @return array
  115. */
  116. private function processBatchQuery(Request $request, string $schemaName = null): array
  117. {
  118. $queries = $this->batchParser->parse($request);
  119. $payloads = [];
  120. foreach ($queries as $query) {
  121. $payload = $this->requestExecutor
  122. ->execute($schemaName, $query)
  123. ->toArray();
  124. if (!$this->useApolloBatchingMethod) {
  125. $payload = ['id' => $query['id'], 'payload' => $payload];
  126. }
  127. $payloads[] = $payload;
  128. }
  129. return $payloads;
  130. }
  131. /**
  132. * @param Request $request
  133. * @param string|null $schemaName
  134. *
  135. * @return array
  136. */
  137. private function processNormalQuery(Request $request, string $schemaName = null): array
  138. {
  139. $params = $this->requestParser->parse($request);
  140. return $this->requestExecutor->execute($schemaName, $params)->toArray();
  141. }
  142. }