vendor/webonyx/graphql-php/src/Server/StandardServer.php line 167

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace GraphQL\Server;
  4. use GraphQL\Error\DebugFlag;
  5. use GraphQL\Error\FormattedError;
  6. use GraphQL\Error\InvariantViolation;
  7. use GraphQL\Executor\ExecutionResult;
  8. use GraphQL\Executor\Promise\Promise;
  9. use GraphQL\Utils\Utils;
  10. use Psr\Http\Message\RequestInterface;
  11. use Psr\Http\Message\ResponseInterface;
  12. use Psr\Http\Message\StreamInterface;
  13. use Throwable;
  14. use function is_array;
  15. /**
  16.  * GraphQL server compatible with both: [express-graphql](https://github.com/graphql/express-graphql)
  17.  * and [Apollo Server](https://github.com/apollographql/graphql-server).
  18.  * Usage Example:
  19.  *
  20.  *     $server = new StandardServer([
  21.  *       'schema' => $mySchema
  22.  *     ]);
  23.  *     $server->handleRequest();
  24.  *
  25.  * Or using [ServerConfig](reference.md#graphqlserverserverconfig) instance:
  26.  *
  27.  *     $config = GraphQL\Server\ServerConfig::create()
  28.  *         ->setSchema($mySchema)
  29.  *         ->setContext($myContext);
  30.  *
  31.  *     $server = new GraphQL\Server\StandardServer($config);
  32.  *     $server->handleRequest();
  33.  *
  34.  * See [dedicated section in docs](executing-queries.md#using-server) for details.
  35.  */
  36. class StandardServer
  37. {
  38.     /** @var ServerConfig */
  39.     private $config;
  40.     /** @var Helper */
  41.     private $helper;
  42.     /**
  43.      * Converts and exception to error and sends spec-compliant HTTP 500 error.
  44.      * Useful when an exception is thrown somewhere outside of server execution context
  45.      * (e.g. during schema instantiation).
  46.      *
  47.      * @param Throwable $error
  48.      * @param int       $debug
  49.      * @param bool      $exitWhenDone
  50.      *
  51.      * @api
  52.      */
  53.     public static function send500Error($error$debug DebugFlag::NONE$exitWhenDone false)
  54.     {
  55.         $response = [
  56.             'errors' => [FormattedError::createFromException($error$debug)],
  57.         ];
  58.         $helper   = new Helper();
  59.         $helper->emitResponse($response500$exitWhenDone);
  60.     }
  61.     /**
  62.      * Creates new instance of a standard GraphQL HTTP server
  63.      *
  64.      * @param ServerConfig|mixed[] $config
  65.      *
  66.      * @api
  67.      */
  68.     public function __construct($config)
  69.     {
  70.         if (is_array($config)) {
  71.             $config ServerConfig::create($config);
  72.         }
  73.         if (! $config instanceof ServerConfig) {
  74.             throw new InvariantViolation('Expecting valid server config, but got ' Utils::printSafe($config));
  75.         }
  76.         $this->config $config;
  77.         $this->helper = new Helper();
  78.     }
  79.     /**
  80.      * Parses HTTP request, executes and emits response (using standard PHP `header` function and `echo`)
  81.      *
  82.      * By default (when $parsedBody is not set) it uses PHP globals to parse a request.
  83.      * It is possible to implement request parsing elsewhere (e.g. using framework Request instance)
  84.      * and then pass it to the server.
  85.      *
  86.      * See `executeRequest()` if you prefer to emit response yourself
  87.      * (e.g. using Response object of some framework)
  88.      *
  89.      * @param OperationParams|OperationParams[] $parsedBody
  90.      * @param bool                              $exitWhenDone
  91.      *
  92.      * @api
  93.      */
  94.     public function handleRequest($parsedBody null$exitWhenDone false)
  95.     {
  96.         $result $this->executeRequest($parsedBody);
  97.         $this->helper->sendResponse($result$exitWhenDone);
  98.     }
  99.     /**
  100.      * Executes GraphQL operation and returns execution result
  101.      * (or promise when promise adapter is different from SyncPromiseAdapter).
  102.      *
  103.      * By default (when $parsedBody is not set) it uses PHP globals to parse a request.
  104.      * It is possible to implement request parsing elsewhere (e.g. using framework Request instance)
  105.      * and then pass it to the server.
  106.      *
  107.      * PSR-7 compatible method executePsrRequest() does exactly this.
  108.      *
  109.      * @param OperationParams|OperationParams[] $parsedBody
  110.      *
  111.      * @return ExecutionResult|ExecutionResult[]|Promise
  112.      *
  113.      * @throws InvariantViolation
  114.      *
  115.      * @api
  116.      */
  117.     public function executeRequest($parsedBody null)
  118.     {
  119.         if ($parsedBody === null) {
  120.             $parsedBody $this->helper->parseHttpRequest();
  121.         }
  122.         if (is_array($parsedBody)) {
  123.             return $this->helper->executeBatch($this->config$parsedBody);
  124.         }
  125.         return $this->helper->executeOperation($this->config$parsedBody);
  126.     }
  127.     /**
  128.      * Executes PSR-7 request and fulfills PSR-7 response.
  129.      *
  130.      * See `executePsrRequest()` if you prefer to create response yourself
  131.      * (e.g. using specific JsonResponse instance of some framework).
  132.      *
  133.      * @return ResponseInterface|Promise
  134.      *
  135.      * @api
  136.      */
  137.     public function processPsrRequest(
  138.         RequestInterface $request,
  139.         ResponseInterface $response,
  140.         StreamInterface $writableBodyStream
  141.     ) {
  142.         $result $this->executePsrRequest($request);
  143.         return $this->helper->toPsrResponse($result$response$writableBodyStream);
  144.     }
  145.     /**
  146.      * Executes GraphQL operation and returns execution result
  147.      * (or promise when promise adapter is different from SyncPromiseAdapter)
  148.      *
  149.      * @return ExecutionResult|ExecutionResult[]|Promise
  150.      *
  151.      * @api
  152.      */
  153.     public function executePsrRequest(RequestInterface $request)
  154.     {
  155.         $parsedBody $this->helper->parsePsrRequest($request);
  156.         return $this->executeRequest($parsedBody);
  157.     }
  158.     /**
  159.      * Returns an instance of Server helper, which contains most of the actual logic for
  160.      * parsing / validating / executing request (which could be re-used by other server implementations)
  161.      *
  162.      * @return Helper
  163.      *
  164.      * @api
  165.      */
  166.     public function getHelper()
  167.     {
  168.         return $this->helper;
  169.     }
  170. }