diff --git a/content/tools/directives/index.md b/content/tools/directives/index.md
index ab5da66..4954fbc 100644
--- a/content/tools/directives/index.md
+++ b/content/tools/directives/index.md
@@ -84,6 +84,6 @@ Wirings run for directives on the following locations:
* `INPUT_OBJECT`
* `INPUT_FIELD_DEFINITION`
-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.
+A directive applied where its definition doesn't allow it, without a required argument, or more than once without being `repeatable` fails the build with a `SchemaError` that lists each of them with its line.
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" >}}).
diff --git a/content/tools/getting-started/index.md b/content/tools/getting-started/index.md
index f451a4f..30b3d8e 100644
--- a/content/tools/getting-started/index.md
+++ b/content/tools/getting-started/index.md
@@ -20,6 +20,8 @@ A working [Kotlin example](https://github.com/graphql-java-kickstart/graphql-jav
To add `graphql-java-tools` to your project and get started quickly, do the following.
+Version 15 needs Java 17, graphql-java 26 and Jackson 3. graphql-spring-boot-starter is archived and doesn't work with it, so stay on 14.5.0 with the starter.
+
### Build with Gradle
Make sure `mavenCentral` is amongst your repositories:
@@ -34,7 +36,7 @@ Add the `graphql-java-tools` dependency:
```gradle
dependencies {
- implementation 'io.github.graphql-java-kickstart:graphql-java-tools:14.5.0'
+ implementation 'io.github.graphql-java-kickstart:graphql-java-tools:15.0.0'
}
```
@@ -46,7 +48,7 @@ Add the `graphql-java-tools` dependency:
io.github.graphql-java-kickstart
graphql-java-tools
- 14.5.0
+ 15.0.0
```
diff --git a/content/tools/schema-definition/index.md b/content/tools/schema-definition/index.md
index 3164827..de28283 100644
--- a/content/tools/schema-definition/index.md
+++ b/content/tools/schema-definition/index.md
@@ -109,7 +109,7 @@ class BookResolver implements GraphQLResolver /* This class is a resolver
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.
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.
The field's arguments come next, in order.
-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.
+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. A method that takes one of these in an argument's place fails the build.
A resolver also applies to subclasses and implementations of its data class, so a `GraphQLResolver` resolves fields for a data class `Thing extends Base`.
A resolver for a generic class, like `GraphQLResolver>`, applies to every `Page`.
diff --git a/content/tools/schema-parser-options/index.md b/content/tools/schema-parser-options/index.md
index d88af54..18b0fcd 100644
--- a/content/tools/schema-parser-options/index.md
+++ b/content/tools/schema-parser-options/index.md
@@ -30,9 +30,12 @@ Options:
* `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`.
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.
* `allowUnimplementedResolvers`: Defaults to `false`. Allows a schema to be created even if not all GraphQL fields have resolvers. Intended only for development, it will log a warning to remind you to turn it off for production. Any unimplemented resolvers will throw errors when queried.
-* `missingResolverDataFetcher`: Allows you to provide custom behavior for missing GraphQL fields.
+* `missingResolverDataFetcherProvider`: Allows you to provide custom behavior for missing GraphQL fields. It gets the field definition and the options, and returns the `DataFetcher` for that field, e.g. `.missingResolverDataFetcherProvider { field, options -> fetcher }`.
* `inputArgumentOptionalDetectOmission`: Defaults to `false`. By default, the parser will treat omitted or null method input arguments as `Optional.empty` in resolvers. If you prefer, you can disable this behavior.
-* `objectMapperConfigurer` / `objectMapperProvider`: Exposes the Jackson `ObjectMapper` that handles marshalling arguments in method resolvers. Every method resolver gets its own mapper, and the configurer can configure it differently based on the GraphQL field definition.
+* `objectMapperConfigurer` / `objectMapperProvider`: The Jackson `ObjectMapper` that converts the arguments of method resolvers. Since 15.0.0 it's Jackson 3 (`tools.jackson`).
+ By default all fields share one mapper with the Kotlin module, which fails on unknown properties and converts enums to and from Strings by `name()`.
+ `objectMapperConfigurer` customizes that mapper per field, and can do it differently based on the GraphQL field definition. It gets the mapper's `JsonMapper.Builder`, e.g. `.objectMapperConfigurer { builder, context -> builder.addModule(MyModule()) }`, and a module added there replaces the library's module of the same type.
+ `objectMapperProvider` uses your own mappers as they are, e.g. `.objectMapperProvider(field -> springMapper)` to share a Spring Boot 4 app's `JsonMapper`.
* `preferGraphQLResolver`: In cases where you have a Resolver class and legacy class that conflict on type arguments, use the Resolver class instead of throwing an error.
Specifically this situation can occur when you have a graphql schema type `Foo` with a `bars` property and classes:
```java
@@ -57,8 +60,10 @@ Options:
* Guice
* Spring AOP
* Weld
-* `introspectionEnabled`: Deprecated, and will be removed in 15.0.0. Defaults to `true`. When set to `false`, every field of the introspection types is hidden, so an introspection query fails validation.
- Turn introspection off with graphql-java instead, for the whole JVM or for one request:
+
+ A resolver that is a JDK dynamic proxy fails the build, since its methods can't be called on the proxy. Use class-based proxies, e.g. `proxyTargetClass = true` in Spring.
+* `fieldVisibility`: Provide a graphql field visibility implementation. See [Field Visibility](https://www.graphql-java.com/documentation/field-visibility).
+ To turn introspection off, use graphql-java's switches, for the whole JVM or for one request:
```java
Introspection.enabledJvmWide(false);
@@ -66,8 +71,6 @@ Options:
.query(query)
.graphQLContext(Map.of(Introspection.INTROSPECTION_DISABLED, true));
```
- An introspection query then fails with an "introspection disabled" error when it runs.
-* `fieldVisibility`: Provide a graphql field visibility implementation. This option overrides `introspectionEnabled` when used. See [Field Visibility](https://www.graphql-java.com/documentation/field-visibility).
* `coroutineContext` / `coroutineContextProvider`: Provide a kotlin coroutine context to be used with suspend functions of resolvers.
A suspend function runs on the calling thread until it first suspends, and continues on this context after that, so wrap blocking calls in `withContext(Dispatchers.IO)`.
To run them in your own `CoroutineScope`, e.g. to cancel them with the request, put it in the execution input's context:
@@ -79,6 +82,6 @@ Options:
* `typeDefinitionFactory`: See [Type Definition Factory]({{< relref "/tools/type-definition-factory/index.md" >}}).
* `includeUnusedTypes`: Defaults to `false`. By default, the parser will ignore unused type definitions in the schema. Enable this option to include them regardless.
* `allowUndeclaredDirectives`: Defaults to `false`. Allows applying directives that aren't declared in the schema, e.g. the Apollo Federation directives imported through `@link`. They're only added as applied directives, with argument types guessed from their values. Directives with enum or input object arguments still have to be declared.
-* `unmappedInputFields`: Defaults to `WARN`. What to do about input type fields that the class of a resolver argument has no property for. When a client sends such a field, Jackson fails to convert the argument, or drops the value if the `ObjectMapper` ignores unknown properties.
- The classes are checked when the schema is built, with each field's own `ObjectMapper`, and `WARN` logs a warning for each of these fields. `FAIL` fails the build instead, and `IGNORE` skips the check. To leave a field unmapped on purpose, add it to `@JsonIgnoreProperties` on the class.
+* `unmappedInputFields`: Defaults to `WARN`. What to do about input type fields that the class of a resolver argument has no property for. When a client sends such a field, Jackson fails to convert the argument, or drops the value if the `ObjectMapper` ignores unknown properties, like plain Jackson 3 and Spring Boot mappers do.
+ The classes are checked when the schema is built, with each field's `ObjectMapper`, and `WARN` logs a warning for each of these fields. `FAIL` fails the build instead, and `IGNORE` skips the check. To leave a field unmapped on purpose, add it to `@JsonIgnoreProperties` on the class.
Classes with a custom deserializer, a builder or a delegating creator aren't checked, and neither are arguments bound to a `Map` or a `JsonNode`.