Skip to content

Commit af95e79

Browse files
committed
Document the tools changes in 14.4.0
1 parent ab1fa61 commit af95e79

4 files changed

Lines changed: 27 additions & 15 deletions

File tree

‎content/tools/directives/index.md‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,12 @@ Arguments the SDL leaves out are filled in with their default from the directive
6868

6969
An enum that's only used by directive definitions doesn't need a Java class. Its values are then passed to the wiring as `String`s. Add the enum to the [type dictionary]({{< relref "/tools/schema-definition/index.md#type-dictionary" >}}) to get the enum constants instead.
7070

71+
Wirings run once the whole schema is built, like in graphql-java, so the types they see are the real ones and not `GraphQLTypeReference`s.
72+
7173
## Supported locations
72-
Support for directives is currently limited to the following locations:
74+
Wirings run for directives on the following locations:
7375

76+
* `SCALAR`
7477
* `OBJECT`
7578
* `FIELD_DEFINITION`
7679
* `ARGUMENT_DEFINITION`
@@ -81,8 +84,6 @@ Support for directives is currently limited to the following locations:
8184
* `INPUT_OBJECT`
8285
* `INPUT_FIELD_DEFINITION`
8386

84-
Meaning directives for the following locations are currently not yet supported:
85-
86-
* `SCALAR`
87+
A directive applied where its definition doesn't allow it, without a required argument, or more than once without being `repeatable` logs a warning. These will fail the build in 15.0.0.
8788

8889
Directives on `schema` and `extend schema` don't run a wiring, but they're added to the schema's applied directives. Like everywhere else, they have to be declared, unless `allowUndeclaredDirectives` is set in the [schema parser options]({{< relref "/tools/schema-parser-options/index.md" >}}).

‎content/tools/getting-started/index.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Add the `graphql-java-tools` dependency:
3434

3535
```gradle
3636
dependencies {
37-
implementation 'io.github.graphql-java-kickstart:graphql-java-tools:14.3.0'
37+
implementation 'io.github.graphql-java-kickstart:graphql-java-tools:14.4.0'
3838
}
3939
```
4040

@@ -46,7 +46,7 @@ Add the `graphql-java-tools` dependency:
4646
<dependency>
4747
<groupId>io.github.graphql-java-kickstart</groupId>
4848
<artifactId>graphql-java-tools</artifactId>
49-
<version>14.3.0</version>
49+
<version>14.4.0</version>
5050
</dependency>
5151
```
5252

‎content/tools/schema-definition/index.md‎

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ class BookResolver implements GraphQLResolver<Book> /* This class is a resolver
108108

109109
When given a `BookResolver` instance, GraphQL Java Tools first attempts to map fields to methods on the resolver before mapping them to fields or methods on the data class.
110110
If there is a matching method on the resolver, the data class instance is passed as the first argument to the resolver function. This does not apply to root resolvers, since those don't have a data class to resolve for.
111-
An optional parameter can be defined to inject the `DataFetchingEnvironment`, and must be the last argument.
111+
The field's arguments come next, in order.
112+
After them, a method can take any of `DataFetchingEnvironment`, `GraphQLContext` and the `contextClass` set in the [schema parser options]({{< relref "/tools/schema-parser-options/index.md" >}}), in any order.
112113

113114
A resolver also applies to subclasses and implementations of its data class, so a `GraphQLResolver<Base>` resolves fields for a data class `Thing extends Base`.
114115
A resolver for a generic class, like `GraphQLResolver<Page<?>>`, applies to every `Page<T>`.
@@ -150,24 +151,32 @@ SchemaParser.newParser()
150151

151152
The field mapping is done by name against public/protected methods and public/protected/private fields, with the following priority:
152153

154+
`*environmentOrContext` stands for any of `DataFetchingEnvironment`, `GraphQLContext` and the `contextClass`, in any order.
155+
153156
First on the resolver or root resolver (note that dataClassInstance doesn't apply for root resolvers):
154157

155-
1. `method <name>(dataClassInstance, *fieldArgs [, DataFetchingEnvironment])`
156-
2. `method is<Name>(dataClassInstance, *fieldArgs [, DataFetchingEnvironment])`, only if the field returns a `Boolean`
157-
3. `method get<Name>(dataClassInstance, *fieldArgs [, DataFetchingEnvironment])`
158-
4. `method getField<Name>(dataClassInstance, *fieldArgs [, DataFetchingEnvironment])`
158+
1. `method <name>(dataClassInstance, *fieldArgs [, *environmentOrContext])`
159+
2. `method is<Name>(dataClassInstance, *fieldArgs [, *environmentOrContext])`, only if the field returns a `Boolean`
160+
3. `method get<Name>(dataClassInstance, *fieldArgs [, *environmentOrContext])`
161+
4. `method getField<Name>(dataClassInstance, *fieldArgs [, *environmentOrContext])`
159162

160163
Then on the data class:
161164

162-
1. `method <name>(*fieldArgs [, DataFetchingEnvironment])`
163-
2. `method is<Name>(*fieldArgs [, DataFetchingEnvironment])`, only if the field returns a `Boolean`
164-
3. `method get<Name>(*fieldArgs [, DataFetchingEnvironment])`
165-
4. `method getField<Name>(*fieldArgs [, DataFetchingEnvironment])`
165+
1. `method <name>(*fieldArgs [, *environmentOrContext])`
166+
2. `method is<Name>(*fieldArgs [, *environmentOrContext])`, only if the field returns a `Boolean`
167+
3. `method get<Name>(*fieldArgs [, *environmentOrContext])`
168+
4. `method getField<Name>(*fieldArgs [, *environmentOrContext])`
166169
5. `field <name>`
167170

168171
Last of all, if the data class implements`java.util.Map` then:
169172
1. `method get(name)`
170173

174+
If nothing above matches, a resolver method can leave out the data class instance, as long as it ends in at least one environment or context parameter:
175+
176+
1. `method <name>(*fieldArgs, *environmentOrContext)`, and the `is`, `get` and `getField` forms in the same order as above
177+
178+
This is for fields that only need the environment, e.g. a value the parent field put in its `localContext`. It doesn't apply when `allowUnimplementedResolvers` or a missing resolver data fetcher is set, since those already handle a field with no match.
179+
171180

172181
<!--*Note:* `java.util.Optional` can be used for nullable field arguments and nullable return values, and the schema parser will verify that it's not used with non-null field arguments and return values.-->
173182

‎content/tools/schema-parser-options/index.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ Options:
2424
```
2525
* `genericWrappers`: Allows defining your own generic classes that should be unwrapped when matching Java types to GraphQL types. You must supply the class and the index (zero-indexed) of the wrapped generic type. For example: If you want to unwrap type argument `T` of `Future<T>`, you must pass `Future.class` and `0`.
2626
Use `GenericWrapper.withTransformer` to also convert the value at runtime. If the transformer returns `null`, the field is `null`.
27+
Wrappers and futures nested in lists or in other wrappers are unwrapped too, e.g. `List<Try<Payload>>` or `List<CompletableFuture<Item>>`. If one element fails, the whole field fails.
28+
A transformer or nested future that calls a DataLoader after an async step needs graphql-java's DataLoader chaining (`DataLoaderDispatchingContextKeys.setEnableDataLoaderChaining`), otherwise the field never completes.
2729

2830
* `useDefaultGenericWrappers`: Defaults to `true`. Tells the parser whether or not to add it's own list of well-known generic wrappers, such as `Future` and `CompletableFuture`.
2931
graphql-java only waits on a `CompletionStage`, so a method declared to return a `Future` has to return one, such as a `CompletableFuture`. Any other future fails the field with an error, unless a generic wrapper transformer converts it.

0 commit comments

Comments
 (0)