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

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