diff --git a/Request/Executor.php b/Request/Executor.php index 85209a75a..e2fdfcdcf 100644 --- a/Request/Executor.php +++ b/Request/Executor.php @@ -11,6 +11,7 @@ namespace Overblog\GraphQLBundle\Request; +use GraphQL\Executor\ExecutionResult; use GraphQL\GraphQL; use GraphQL\Schema; use GraphQL\Validator\DocumentValidator; @@ -24,6 +25,8 @@ class Executor { + const DEFAULT_EXECUTOR = 'GraphQL\\GraphQL::executeAndReturnResult'; + /** * @var Schema[] */ @@ -43,12 +46,35 @@ class Executor /** @var bool */ private $hasDebugInfo; - public function __construct(EventDispatcherInterface $dispatcher = null, $throwException = false, ErrorHandler $errorHandler = null, $hasDebugInfo = false) + /** + * @var callable + */ + private $executor; + + public function __construct( + EventDispatcherInterface $dispatcher = null, + $throwException = false, + ErrorHandler $errorHandler = null, + $hasDebugInfo = false, + callable $executor = null + ) { $this->dispatcher = $dispatcher; $this->throwException = (bool) $throwException; $this->errorHandler = $errorHandler; $hasDebugInfo ? $this->enabledDebugInfo() : $this->disabledDebugInfo(); + $this->executor = $executor; + if (null === $this->executor) { + $this->executor = self::DEFAULT_EXECUTOR; + } + + } + + public function setExecutor(callable $executor) + { + $this->executor = $executor; + + return $this; } public function addSchema($name, Schema $schema) @@ -116,7 +142,8 @@ public function execute(array $data, array $context = [], $schemaName = null) $startTime = microtime(true); $startMemoryUsage = memory_get_usage(true); - $executionResult = GraphQL::executeAndReturnResult( + $executionResult = call_user_func( + $this->executor, $schema, isset($data[ParserInterface::PARAM_QUERY]) ? $data[ParserInterface::PARAM_QUERY] : null, $context, @@ -125,6 +152,10 @@ public function execute(array $data, array $context = [], $schemaName = null) isset($data[ParserInterface::PARAM_OPERATION_NAME]) ? $data[ParserInterface::PARAM_OPERATION_NAME] : null ); + if (!is_object($executionResult) || !$executionResult instanceof ExecutionResult) { + throw new \RuntimeException(sprintf('Execution result should be an object instantiating "%s".', 'GraphQL\\Executor\\ExecutionResult')); + } + if ($this->hasDebugInfo()) { $executionResult->extensions['debug'] = [ 'executionTime' => sprintf('%d ms', round(microtime(true) - $startTime, 1) * 1000), diff --git a/Resources/config/services.yml b/Resources/config/services.yml index cf2cae6af..032854797 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -1,6 +1,7 @@ parameters: overblog_graphql.default_resolver: [Overblog\GraphQLBundle\Resolver\Resolver, defaultResolveFn] overblog_graphql.type_class_namespace: "Overblog\\GraphQLBundle\\__DEFINITIONS__" + overblog_graphql.default_executor: [GraphQL\GraphQL, executeAndReturnResult] services: overblog_graphql.error_handler: @@ -18,6 +19,7 @@ services: - "%kernel.debug%" - "@overblog_graphql.error_handler" - false + - "%overblog_graphql.default_executor%" calls: - ["setMaxQueryComplexity", ["%overblog_graphql.query_max_complexity%"]] - ["setMaxQueryDepth", ["%overblog_graphql.query_max_depth%"]] diff --git a/Tests/Request/ExecutorTest.php b/Tests/Request/ExecutorTest.php index ed1e5e196..b30fb17fd 100644 --- a/Tests/Request/ExecutorTest.php +++ b/Tests/Request/ExecutorTest.php @@ -26,17 +26,47 @@ class ExecutorTest extends \PHPUnit_Framework_TestCase public function setUp() { $this->executor = new Executor(); + $queryType = new ObjectType([ + 'name' => 'Query', + 'fields' => [ + 'myField' => [ + 'type' => Type::boolean(), + 'resolve' => function () { + return false; + }, + ], + ], + ]); + $this->executor->addSchema('global', new Schema(['query' => $queryType])); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Execution result should be an object instantiating "GraphQL\Executor\ExecutionResult". + */ + public function testInvalidExecutorReturnNotObject() + { + $this->executor->setExecutor(function() { return false; }); + $this->executor->execute($this->request); + } + + /** + * @expectedException \RuntimeException + * @expectedExceptionMessage Execution result should be an object instantiating "GraphQL\Executor\ExecutionResult". + */ + public function testInvalidExecutorReturnInvalidObject() + { + $this->executor->setExecutor(function() { return new \stdClass(); }); + $this->executor->execute($this->request); } public function testDisabledDebugInfo() { - $this->addSchema(); $this->assertArrayNotHasKey('debug', $this->executor->disabledDebugInfo()->execute($this->request)->extensions); } public function testEnabledDebugInfo() { - $this->addSchema(); $result = $this->executor->enabledDebugInfo()->execute($this->request); $this->assertArrayHasKey('debug', $result->extensions); @@ -50,23 +80,6 @@ public function testEnabledDebugInfo() */ public function testGetSchemaNoSchemaFound() { - $this->executor->getSchema('fake'); - } - - private function addSchema() - { - $queryType = new ObjectType([ - 'name' => 'Query', - 'fields' => [ - 'myField' => [ - 'type' => Type::boolean(), - 'resolve' => function () { - return false; - }, - ], - ], - ]); - - $this->executor->addSchema('global', new Schema(['query' => $queryType])); + (new Executor())->getSchema('fake'); } }