Skip to content

Commit afc1069

Browse files
committed
Clean up around resolveField option
1 parent 06daa1e commit afc1069

File tree

5 files changed

+49
-62
lines changed

5 files changed

+49
-62
lines changed

benchmarks/Utils/SchemaGenerator.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ protected function createType(int $nestingLevel, ?string $typeName = null): Obje
6363

6464
++$this->typeIndex;
6565
if ($typeName === null) {
66-
$typeName = 'Level_' . $nestingLevel . '_Type' . $this->typeIndex;
66+
$typeName = "Level_{$nestingLevel}_Type{$this->typeIndex}";
6767
}
6868

6969
$type = new ObjectType([
@@ -81,13 +81,13 @@ protected function getFieldTypeAndName(int $nestingLevel, int $fieldIndex): arra
8181
{
8282
if ($nestingLevel >= $this->config['nestingLevel']) {
8383
$fieldType = Type::string();
84-
$fieldName = 'leafField' . $fieldIndex;
84+
$fieldName = "leafField{$fieldIndex}";
8585
} elseif ($this->typeIndex >= $this->config['totalTypes']) {
8686
$fieldType = $this->objectTypes[array_rand($this->objectTypes)];
87-
$fieldName = 'randomTypeField' . $fieldIndex;
87+
$fieldName = "randomTypeField{$fieldIndex}";
8888
} else {
8989
$fieldType = $this->createType($nestingLevel);
90-
$fieldName = 'field' . $fieldIndex;
90+
$fieldName = "field{$fieldIndex}";
9191
}
9292

9393
return [$fieldType, $fieldName];
@@ -136,7 +136,7 @@ protected function createFieldArgs(string $fieldName, string $typeName): array
136136
],
137137
'argEnum' => [
138138
'type' => new EnumType([
139-
'name' => $typeName . $fieldName . 'Enum',
139+
'name' => "{$typeName}{$fieldName}Enum",
140140
'values' => [
141141
'ONE',
142142
'TWO',
@@ -146,7 +146,7 @@ protected function createFieldArgs(string $fieldName, string $typeName): array
146146
],
147147
'argInputObject' => [
148148
'type' => new InputObjectType([
149-
'name' => $typeName . $fieldName . 'Input',
149+
'name' => "{$typeName}{$fieldName}Input",
150150
'fields' => [
151151
'field1' => Type::string(),
152152
'field2' => Type::int(),
@@ -163,6 +163,6 @@ protected function createFieldArgs(string $fieldName, string $typeName): array
163163
*/
164164
public function resolveField($root, array $args, $context, ResolveInfo $resolveInfo): string
165165
{
166-
return $resolveInfo->fieldName . '-value';
166+
return "{$resolveInfo->fieldName}-value";
167167
}
168168
}

docs/data-fetching.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,9 @@ To override the default resolver, pass it as an argument to [executeQuery](execu
123123

124124
## Default Field Resolver per Type
125125

126-
Sometimes it might be convenient to set default field resolver per type. You can do so by providing
127-
[resolveField option in type config](type-definitions/object-types.md#configuration-options). For example:
126+
Sometimes it might be convenient to set a default field resolver per type.
127+
You can do so by providing [the **resolveField** option in the type config](type-definitions/object-types.md#configuration-options).
128+
For example:
128129

129130
```php
130131
use GraphQL\Type\Definition\Type;
@@ -137,7 +138,7 @@ $userType = new ObjectType([
137138
'name' => Type::string(),
138139
'email' => Type::string()
139140
],
140-
'resolveField' => function (User $user, array $args, $context, ResolveInfo $info) {
141+
'resolveField' => function (User $user, array $args, $context, ResolveInfo $info): ?string {
141142
switch ($info->fieldName) {
142143
case 'name': return $user->getName();
143144
case 'email': return $user->getEmail();

docs/schema-definition-language.md

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
# Schema Definition Language
22

3-
Since 0.9.0
4-
53
The [schema definition language](https://graphql.org/learn/schema/#type-language) is a convenient way to define your schema,
64
especially with IDE autocompletion and syntax validation.
75

8-
You can define this separate from your PHP code, e.g. in a **schema.graphql** file:
6+
You can define this separately from your PHP code.
7+
An example for a **schema.graphql** file might look like this:
98

109
```graphql
11-
schema {
12-
query: Query
13-
mutation: Mutation
14-
}
15-
1610
type Query {
1711
greetings(input: HelloInput!): String!
1812
}
@@ -23,8 +17,7 @@ input HelloInput {
2317
}
2418
```
2519

26-
In order to create schema instance out of this file, use
27-
[`GraphQL\Utils\BuildSchema`](class-reference.md#graphqlutilsbuildschema):
20+
To create an executable schema instance from this file, use [`GraphQL\Utils\BuildSchema`](class-reference.md#graphqlutilsbuildschema):
2821

2922
```php
3023
use GraphQL\Utils\BuildSchema;
@@ -33,19 +26,16 @@ $contents = file_get_contents('schema.graphql');
3326
$schema = BuildSchema::build($contents);
3427
```
3528

36-
By default, such schema is created without any resolvers.
37-
38-
We have to rely on [default field resolver](data-fetching.md#default-field-resolver) and **root value** in
39-
order to execute a query against this schema.
29+
By default, such a schema is created without any resolvers.
30+
We have to rely on [the default field resolver](data-fetching.md#default-field-resolver)
31+
and the **root value** to execute queries against this schema.
4032

4133
## Defining resolvers
4234

43-
Since 0.10.0
44-
45-
In order to enable **Interfaces**, **Unions** and custom field resolvers you can pass the second argument:
46-
**type config decorator** to schema builder.
35+
To enable **Interfaces**, **Unions**, and custom field resolvers,
36+
you can pass the second argument **callable $typeConfigDecorator** to **BuildSchema::build()**.
4737

48-
It accepts default type config produced by the builder and is expected to add missing options like
38+
It accepts a callable that receives the default type config produced by the builder and is expected to add missing options like
4939
[**resolveType**](type-definitions/interfaces.md#configuration-options) for interface types or
5040
[**resolveField**](type-definitions/object-types.md#configuration-options) for object types.
5141

@@ -65,13 +55,11 @@ $schema = BuildSchema::build($contents, $typeConfigDecorator);
6555

6656
## Performance considerations
6757

68-
Since 0.10.0
69-
70-
Method **build()** produces a [lazy schema](schema-definition.md#lazy-loading-of-types)
71-
automatically, so it works efficiently even with very large schemas.
58+
Method **BuildSchema::build()** produces a [lazy schema](schema-definition.md#lazy-loading-of-types) automatically,
59+
so it works efficiently even with huge schemas.
7260

73-
But parsing type definition file on each request is suboptimal, so it is recommended to cache
74-
intermediate parsed representation of the schema for the production environment:
61+
However, parsing the schema definition file on each request is suboptimal.
62+
It is recommended to cache the intermediate parsed representation of the schema for the production environment:
7563

7664
```php
7765
use GraphQL\Language\Parser;

docs/type-definitions/interfaces.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -122,20 +122,18 @@ $humanType = new ObjectType([
122122
]);
123123
```
124124

125-
In this case, field definitions are created only once (as a part of Interface Type) and then
126-
reused by all interface implementors. It can save several microseconds and kilobytes + ensures that
127-
field definitions of Interface and implementors are always in sync.
125+
In this case, field definitions are created only once (as a part of the Interface Type) and then reused by all interface implementors.
126+
It can save several microseconds and kilobytes and ensures that field definitions of Interface and implementors are always in sync.
127+
Yet it creates a problem with the resolution of such fields.
128128

129-
Yet it creates a problem with the resolution of such fields. There are two ways how shared fields could
130-
be resolved:
129+
There are two ways how shared fields could be resolved:
131130

132-
1. If field resolution algorithm is the same for all Interface implementors - you can simply add
133-
**resolve** option to field definition in Interface itself.
131+
1. If the field resolution algorithm is the same for all Interface implementors,
132+
you can add the **resolve** option to the field definition in the Interface itself.
134133

135-
2. If field resolution varies for different implementations - you can specify **resolveField**
136-
option in [Object Type config](object-types.md#configuration-options) and handle field
137-
resolutions there
138-
(Note: **resolve** option in field definition has precedence over **resolveField** option in object type definition)
134+
2. If field resolution varies for different implementations, you can specify the **resolveField** option
135+
in [the Object Type config](object-types.md#configuration-options) and handle field resolutions there.
136+
(Note: The **resolve** option in field definitions has precedence over the **resolveField** option in object type definitions.)
139137

140138
## Interface role in data fetching
141139

docs/type-definitions/object-types.md

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,16 @@ This example uses **inline** style for Object Type definitions, but you can also
5858

5959
## Configuration options
6060

61-
| Option | Type | Notes |
62-
| ------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
63-
| name | `string` | **Required.** Unique name of this object type within Schema |
64-
| fields | `array` or `callable` | **Required**. An array describing object fields or callable returning such an array. See [field configuration options](#field-configuration-options) section below for expected structure of each array entry. See also the section on [Circular types](#recurring-and-circular-types) for an explanation of when to use callable for this option. |
65-
| description | `string` | Plain-text description of this type for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation) |
66-
| interfaces | `array` or `callable` | List of interfaces implemented by this type or callable returning such a list. See [Interface Types](interfaces.md) for details. See also the section on [Circular types](#recurring-and-circular-types) for an explanation of when to use callable for this option. |
67-
| isTypeOf | `callable` | **function ($value, $context, [ResolveInfo](../class-reference.md#graphqltypedefinitionresolveinfo) $info): bool**<br> Expected to return **true** if **$value** qualifies for this type (see section about [Abstract Type Resolution](interfaces.md#interface-role-in-data-fetching) for explanation). |
68-
| resolveField | `callable` | **function ($value, array $args, $context, [ResolveInfo](../class-reference.md#graphqltypedefinitionresolveinfo) $info): mixed**<br> Given the **$value** of this type, it is expected to return value for a field defined in **$info->fieldName**. A good place to define a type-specific strategy for field resolution. See section on [Data Fetching](../data-fetching.md) for details. |
69-
| argsMapper | `callable` | **function (array $args, FieldDefinition, FieldNode): mixed**<br> Called once, when Executor resolves arguments for given field. Could be used to validate args and/or to map them to DTO/Object. |
70-
| visible | `bool` or `callable` | Defaults to `true`. The given callable receives no arguments and is expected to return a `bool`, it is called once when the field may be accessed. The field is treated as if it were not defined at all when this is `false`. |
61+
| Option | Type | Notes |
62+
|--------------|-----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
63+
| name | `string` | **Required.** Unique name of this object type within Schema |
64+
| fields | `array` or `callable` | **Required**. An array describing object fields or callable returning such an array. See [field configuration options](#field-configuration-options) section below for expected structure of each array entry. See also the section on [Circular types](#recurring-and-circular-types) for an explanation of when to use callable for this option. |
65+
| description | `string` | Plain-text description of this type for clients (e.g. used by [GraphiQL](https://github.com/graphql/graphiql) for auto-generated documentation) |
66+
| interfaces | `array` or `callable` | List of interfaces implemented by this type or callable returning such a list. See [Interface Types](interfaces.md) for details. See also the section on [Circular types](#recurring-and-circular-types) for an explanation of when to use callable for this option. |
67+
| isTypeOf | `callable` | **function ($value, $context, [ResolveInfo](../class-reference.md#graphqltypedefinitionresolveinfo) $info): bool**<br> Expected to return **true** if **$value** qualifies for this type (see section about [Abstract Type Resolution](interfaces.md#interface-role-in-data-fetching) for explanation). |
68+
| resolveField | `callable` | **function ($value, array $args, $context, [ResolveInfo](../class-reference.md#graphqltypedefinitionresolveinfo) $info): mixed**<br> Given the **$value** of this type, it is expected to return value for a field defined in **$info->fieldName**. A good place to define a type-specific strategy for field resolution. See [Data Fetching](../data-fetching.md) for details. |
69+
| argsMapper | `callable` | **function (array $args, FieldDefinition, FieldNode): mixed**<br> Called once, when Executor resolves arguments for given field. Could be used to validate args and/or to map them to DTO/Object. |
70+
| visible | `bool` or `callable` | Defaults to `true`. The given callable receives no arguments and is expected to return a `bool`, it is called once when the field may be accessed. The field is treated as if it were not defined at all when this is `false`. |
7171

7272
### Field configuration options
7373

@@ -196,15 +196,15 @@ class MyTypes
196196
## Field Resolution
197197

198198
Field resolution is the primary mechanism in **graphql-php** for returning actual data for your fields.
199-
It is implemented using **resolveField** callable in type definition or **resolve**
200-
callable in field definition (which has precedence).
199+
It is implemented using a **resolveField** callable in type definitions,
200+
or a **resolve** callable in field definitions (the latter has precedence).
201201

202202
Read the section on [Data Fetching](../data-fetching.md) for a complete description of this process.
203203

204204
## Custom Metadata
205205

206-
All types in **graphql-php** accept configuration array. In some cases, you may be interested in
207-
passing your own metadata for type or field definition.
206+
All types in **graphql-php** accept a configuration array.
207+
In some cases, you may be interested in passing your own metadata for type or field definition.
208208

209-
**graphql-php** preserves original configuration array in every type or field instance in
210-
public property **$config**. Use it to implement app-level mappings and definitions.
209+
**graphql-php** preserves the original configuration array in every type or field instance in a public property **$config**.
210+
You may use it for custom implementations that are not natively supported by this library.

0 commit comments

Comments
 (0)