GraphQl.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\GraphQl\Controller;
  8. use Magento\Framework\App\FrontControllerInterface;
  9. use Magento\Framework\App\Request\Http;
  10. use Magento\Framework\App\RequestInterface;
  11. use Magento\Framework\App\ResponseInterface;
  12. use Magento\Framework\GraphQl\Exception\ExceptionFormatter;
  13. use Magento\Framework\GraphQl\Query\QueryProcessor;
  14. use Magento\Framework\GraphQl\Query\Resolver\ContextInterface;
  15. use Magento\Framework\GraphQl\Schema\SchemaGeneratorInterface;
  16. use Magento\Framework\Serialize\SerializerInterface;
  17. use Magento\Framework\Webapi\Response;
  18. use Magento\Framework\GraphQl\Query\Fields as QueryFields;
  19. /**
  20. * Front controller for web API GraphQL area.
  21. *
  22. * @api
  23. * @since 100.3.0
  24. */
  25. class GraphQl implements FrontControllerInterface
  26. {
  27. /**
  28. * @var Response
  29. */
  30. private $response;
  31. /**
  32. * @var SchemaGeneratorInterface
  33. */
  34. private $schemaGenerator;
  35. /**
  36. * @var SerializerInterface
  37. */
  38. private $jsonSerializer;
  39. /**
  40. * @var QueryProcessor
  41. */
  42. private $queryProcessor;
  43. /**
  44. * @var \Magento\Framework\GraphQl\Exception\ExceptionFormatter
  45. */
  46. private $graphQlError;
  47. /**
  48. * @var \Magento\Framework\GraphQl\Query\Resolver\ContextInterface
  49. */
  50. private $resolverContext;
  51. /**
  52. * @var HttpRequestProcessor
  53. */
  54. private $requestProcessor;
  55. /**
  56. * @var QueryFields
  57. */
  58. private $queryFields;
  59. /**
  60. * @param Response $response
  61. * @param SchemaGeneratorInterface $schemaGenerator
  62. * @param SerializerInterface $jsonSerializer
  63. * @param QueryProcessor $queryProcessor
  64. * @param \Magento\Framework\GraphQl\Exception\ExceptionFormatter $graphQlError
  65. * @param \Magento\Framework\GraphQl\Query\Resolver\ContextInterface $resolverContext
  66. * @param HttpRequestProcessor $requestProcessor
  67. * @param QueryFields $queryFields
  68. */
  69. public function __construct(
  70. Response $response,
  71. SchemaGeneratorInterface $schemaGenerator,
  72. SerializerInterface $jsonSerializer,
  73. QueryProcessor $queryProcessor,
  74. ExceptionFormatter $graphQlError,
  75. ContextInterface $resolverContext,
  76. HttpRequestProcessor $requestProcessor,
  77. QueryFields $queryFields
  78. ) {
  79. $this->response = $response;
  80. $this->schemaGenerator = $schemaGenerator;
  81. $this->jsonSerializer = $jsonSerializer;
  82. $this->queryProcessor = $queryProcessor;
  83. $this->graphQlError = $graphQlError;
  84. $this->resolverContext = $resolverContext;
  85. $this->requestProcessor = $requestProcessor;
  86. $this->queryFields = $queryFields;
  87. }
  88. /**
  89. * Handle GraphQL request
  90. *
  91. * @param RequestInterface $request
  92. * @return ResponseInterface
  93. * @since 100.3.0
  94. */
  95. public function dispatch(RequestInterface $request) : ResponseInterface
  96. {
  97. $statusCode = 200;
  98. try {
  99. /** @var Http $request */
  100. $this->requestProcessor->processHeaders($request);
  101. $data = $this->jsonSerializer->unserialize($request->getContent());
  102. $query = isset($data['query']) ? $data['query'] : '';
  103. $variables = isset($data['variables']) ? $data['variables'] : null;
  104. // We have to extract queried field names to avoid instantiation of non necessary fields in webonyx schema
  105. // Temporal coupling is required for performance optimization
  106. $this->queryFields->setQuery($query, $variables);
  107. $schema = $this->schemaGenerator->generate();
  108. $result = $this->queryProcessor->process(
  109. $schema,
  110. $query,
  111. $this->resolverContext,
  112. isset($data['variables']) ? $data['variables'] : []
  113. );
  114. } catch (\Exception $error) {
  115. $result['errors'] = isset($result) && isset($result['errors']) ? $result['errors'] : [];
  116. $result['errors'][] = $this->graphQlError->create($error);
  117. $statusCode = ExceptionFormatter::HTTP_GRAPH_QL_SCHEMA_ERROR_STATUS;
  118. }
  119. $this->response->setBody($this->jsonSerializer->serialize($result))->setHeader(
  120. 'Content-Type',
  121. 'application/json'
  122. )->setHttpResponseCode($statusCode);
  123. return $this->response;
  124. }
  125. }