Skip to content

Commit ce9bf33

Browse files
committed
Ability to load types in schema on demand (#69)
1 parent d5866e1 commit ce9bf33

File tree

15 files changed

+688
-195
lines changed

15 files changed

+688
-195
lines changed

benchmarks/HugeSchemaBench.php

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class HugeSchemaBench
2222
private $schemaBuilder;
2323

2424
/**
25-
* @var array
25+
* @var Schema\Descriptor
2626
*/
2727
private $descriptor;
2828

@@ -54,7 +54,9 @@ public function setUp()
5454
public function benchSchema()
5555
{
5656
$this->schemaBuilder
57-
->buildSchema();
57+
->buildSchema()
58+
->getTypeMap()
59+
;
5860
}
5961

6062
public function benchSchemaLazy()
@@ -75,16 +77,13 @@ public function benchSmallQueryLazy()
7577

7678
private function createLazySchema()
7779
{
78-
$strategy = new LazyResolution(
79-
$this->descriptor,
80-
function($name) {
81-
return $this->schemaBuilder->loadType($name);
82-
}
80+
return new Schema(
81+
Schema\Config::create()
82+
->setQuery($this->schemaBuilder->buildQueryType())
83+
// ->setDescriptor($this->descriptor)
84+
->setTypeLoader(function($name) {
85+
return $this->schemaBuilder->loadType($name);
86+
})
8387
);
84-
85-
return new Schema([
86-
'query' => $this->schemaBuilder->buildQueryType(),
87-
'typeResolution' => $strategy,
88-
]);
8988
}
9089
}

src/Executor/Executor.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use GraphQL\Error\InvariantViolation;
66
use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter;
77
use GraphQL\Executor\Promise\Promise;
8+
use GraphQL\GraphQL;
89
use GraphQL\Language\AST\DocumentNode;
910
use GraphQL\Language\AST\FieldNode;
1011
use GraphQL\Language\AST\FragmentDefinitionNode;
@@ -16,6 +17,7 @@
1617
use GraphQL\Type\Definition\AbstractType;
1718
use GraphQL\Type\Definition\Directive;
1819
use GraphQL\Type\Definition\FieldDefinition;
20+
use GraphQL\Type\Definition\InterfaceType;
1921
use GraphQL\Type\Definition\LeafType;
2022
use GraphQL\Type\Definition\ListOfType;
2123
use GraphQL\Type\Definition\NonNull;
@@ -974,6 +976,16 @@ private function completeAbstractValue(AbstractType $returnType, $fieldNodes, Re
974976
$runtimeType = $returnType->resolveType($result, $exeContext->contextValue, $info);
975977

976978
if (null === $runtimeType) {
979+
if ($returnType instanceof InterfaceType && !$exeContext->schema->getConfig()->descriptor &&
980+
!GraphQL::isIgnoredError(GraphQL::WARNING_ON_IMPLEMENTATION_RESOLUTION)) {
981+
trigger_error(
982+
"GraphQL Interface Type `{$returnType->name}` returned `null` from it`s `resolveType` function ".
983+
'for value: ' . Utils::printSafe($result) . '. Switching to slow resolution method using `isTypeOf` ' .
984+
'of all possible implementations. It degrades query performance significantly. '.
985+
' Make sure your `resolveType` always returns valid implementation or throws.',
986+
E_USER_WARNING
987+
);
988+
}
977989
$runtimeType = self::inferTypeOf($result, $exeContext->contextValue, $info, $returnType);
978990
}
979991

src/GraphQL.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@
1616

1717
class GraphQL
1818
{
19+
const WARNING_ON_IMPLEMENTATION_RESOLUTION = 1;
20+
21+
private static $ignoredErrors = [];
22+
23+
public static function setIgnoreError($errorCode, $set = true)
24+
{
25+
self::$ignoredErrors[$errorCode] = $set ? true : null;
26+
}
27+
28+
public static function isIgnoredError($errorCode)
29+
{
30+
return isset(self::$ignoredErrors[$errorCode]);
31+
}
32+
1933
/**
2034
* @param Schema $schema
2135
* @param string|DocumentNode $requestString

0 commit comments

Comments
 (0)