You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/DefiningSchema.md
+67-33Lines changed: 67 additions & 33 deletions
Original file line number
Diff line number
Diff line change
@@ -116,7 +116,7 @@ final class Starship extends Type
116
116
117
117
Fields are defined using `getFieldDefinition` function. This is (apart from secondary performance advantages) done because of a possible cyclic dependency across fields. Fields are therefore loaded lazily using this method, instead of passing FieldSet directly to constructor.
118
118
119
-
The `validateNonNullValue` function allows the programmer to check if the parent resolver passed a correct value for this type. When false an `InvalidValue` is thrown.
119
+
The `validateNonNullValue` function allows the programmer to check if the parent resolver passed a correct value for this type. The argument is any value resolved from parent resolver, except `null` which has a special meaning for the GraphQL. When the function returns `false` an `InvalidValue` is thrown.
120
120
121
121
#### Implementing interface
122
122
@@ -150,6 +150,8 @@ interface Character {
150
150
151
151
namespaceApp\Type;
152
152
153
+
useApp\Dto\HumanasHumanDto;
154
+
useApp\Dto\DroidasDroidDto;
153
155
useApp\Type\Episode;
154
156
useGraphpinator\Typesystem\Attribute\Description;
155
157
useGraphpinator\Typesystem\Container;
@@ -160,40 +162,53 @@ use Graphpinator\Typesystem\InterfaceType;
Fields are defined using `getFieldDefinition` function using the same concept as for defining Types. The only difference is the absence of a resolve function, because Interfaces cannot be resolved directly. Field definitions are used to validate contract with Types implementing this interface.
207
+
Fields are defined using `getFieldDefinition` function using the same concept as for defining `Type`. The only difference is the absence of a resolve function, because Interfaces cannot be resolved directly. Field definitions are used to validate contract with Types implementing this interface.
208
+
209
+
Additionally, the `createResolvedValue` function must be implemented to decide which concrete type the resolved value belongs to. The argument is any value resolved from parent resolver, except `null` which has a special meaning for the GraphQL. The result of this method is a structure of the concrete type and the undelying value which will be passed into it.
210
+
211
+
This may cause trouble as the cyclic dependency appears, the contrete types need the interface in order to implement it and the interface need the conrete types in order to resolve the value. This is a common scenario in the GraphQL, as the types reference each other and can resolve in cycles. In this example we worked around it by passing an accessor as a constructor dependency instead of the types directly. The implementation of the accessor depends on which framework and/or DI solution you use.
197
212
198
213
Interfaces can also implement other interfaces using the same procedure as types - passing `InterfaceSet` into parent constructor.
199
214
In this case the fields from parent interface are automatically included and there is no need to repeat the field definitions in the child, unless you wish to be more specific - but keep in mind that covariance/contravariance rules must be applied.
@@ -211,25 +226,44 @@ union SearchResult = Human | Droid | Starship
0 commit comments