Skip to content

Commit

Permalink
Allow lazy root type callables to return null
Browse files Browse the repository at this point in the history
  • Loading branch information
spawnia authored Aug 7, 2023
1 parent a92b074 commit 86d5a65
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 10 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ You can find and compare releases at the [GitHub release page](https://github.co

## Unreleased

## v15.6.1

### Fixed

- Allow lazy root type callables to return `null` https://github.com/webonyx/graphql-php/pull/1422

## v15.6.0

### Added
Expand Down
2 changes: 1 addition & 1 deletion docs/class-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ Usage example:

@see Type, NamedType

@phpstan-type MaybeLazyObjectType ObjectType|(callable(): ObjectType)|null
@phpstan-type MaybeLazyObjectType ObjectType|(callable(): (ObjectType|null))|null
@phpstan-type TypeLoader callable(string $typeName): ((Type&NamedType)|null)
@phpstan-type Types iterable<Type&NamedType>|(callable(): iterable<Type&NamedType>)
@phpstan-type SchemaConfigOptions array{
Expand Down
16 changes: 8 additions & 8 deletions docs/schema-definition.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,14 @@ with complex input values (see [Mutations and Input Types](type-definitions/inpu
The schema constructor expects an instance of [`GraphQL\Type\SchemaConfig`](class-reference.md#graphqltypeschemaconfig)
or an array with the following options:

| Option | Type | Notes |
| ------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| query | `ObjectType` or `callable(): ObjectType` or `null` | **Required.** Object type (usually named `Query`) containing root-level fields of your read API |
| mutation | `ObjectType` or `callable(): ObjectType` or `null` | Object type (usually named `Mutation`) containing root-level fields of your write API |
| subscription | `ObjectType` or `callable(): ObjectType` or `null` | Reserved for future subscriptions implementation. Currently presented for compatibility with introspection query of **graphql-js**, used by various clients (like Relay or GraphiQL) |
| directives | `array<Directive>` | A full list of [directives](type-definitions/directives.md) supported by your schema. By default, contains built-in **@skip** and **@include** directives.<br><br> If you pass your own directives and still want to use built-in directives - add them explicitly. For example:<br><br> _array_merge(GraphQL::getStandardDirectives(), [$myCustomDirective]);_ |
| types | `array<ObjectType>` | List of object types which cannot be detected by **graphql-php** during static schema analysis.<br><br>Most often this happens when the object type is never referenced in fields directly but is still a part of a schema because it implements an interface which resolves to this object type in its **resolveType** callable. <br><br> Note that you are not required to pass all of your types here - it is simply a workaround for a concrete use-case. |
| typeLoader | `callable(string $name): Type` | Expected to return a type instance given the name. Must always return the same instance if called multiple times, see [lazy loading](#lazy-loading-of-types). See section below on lazy type loading. |
| Option | Type | Notes |
| ------------ | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| query | `ObjectType` or `callable(): ?ObjectType` or `null` | **Required.** Object type (usually named `Query`) containing root-level fields of your read API |
| mutation | `ObjectType` or `callable(): ?ObjectType` or `null` | Object type (usually named `Mutation`) containing root-level fields of your write API |
| subscription | `ObjectType` or `callable(): ?ObjectType` or `null` | Reserved for future subscriptions implementation. Currently presented for compatibility with introspection query of **graphql-js**, used by various clients (like Relay or GraphiQL) |
| directives | `array<Directive>` | A full list of [directives](type-definitions/directives.md) supported by your schema. By default, contains built-in **@skip** and **@include** directives.<br><br> If you pass your own directives and still want to use built-in directives - add them explicitly. For example:<br><br> _array_merge(GraphQL::getStandardDirectives(), [$myCustomDirective]);_ |
| types | `array<ObjectType>` | List of object types which cannot be detected by **graphql-php** during static schema analysis.<br><br>Most often this happens when the object type is never referenced in fields directly but is still a part of a schema because it implements an interface which resolves to this object type in its **resolveType** callable. <br><br> Note that you are not required to pass all of your types here - it is simply a workaround for a concrete use-case. |
| typeLoader | `callable(string $name): Type` | Expected to return a type instance given the name. Must always return the same instance if called multiple times, see [lazy loading](#lazy-loading-of-types). See section below on lazy type loading. |

### Using config class

Expand Down
2 changes: 1 addition & 1 deletion src/Type/SchemaConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
*
* @see Type, NamedType
*
* @phpstan-type MaybeLazyObjectType ObjectType|(callable(): ObjectType)|null
* @phpstan-type MaybeLazyObjectType ObjectType|(callable(): (ObjectType|null))|null
* @phpstan-type TypeLoader callable(string $typeName): ((Type&NamedType)|null)
* @phpstan-type Types iterable<Type&NamedType>|(callable(): iterable<Type&NamedType>)
* @phpstan-type SchemaConfigOptions array{
Expand Down
13 changes: 13 additions & 0 deletions tests/Type/LazyDefinitionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,17 @@ public function testLazyRootTypes(): void
self::assertSame($schema->getMutationType(), $mutation);
self::assertSame($schema->getSubscriptionType(), $subscription);
}

public function testLazyRootTypesNull(): void
{
$schema = new Schema([
'query' => fn () => null,
'mutation' => fn () => null,
'subscription' => fn () => null,
]);

self::assertNull($schema->getQueryType());
self::assertNull($schema->getMutationType());
self::assertNull($schema->getSubscriptionType());
}
}

0 comments on commit 86d5a65

Please sign in to comment.