From 8d3d03e4a33898741102e0d92d64d4887d9d829b Mon Sep 17 00:00:00 2001 From: Oryan Date: Tue, 3 Nov 2026 15:08:12 -0500 Subject: [PATCH 1/2] Document GenericWrapper.withCompletionStageTransformer --- content/tools/schema-parser-options/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/tools/schema-parser-options/index.md b/content/tools/schema-parser-options/index.md index 18b0fcd..5d3efb0 100644 --- a/content/tools/schema-parser-options/index.md +++ b/content/tools/schema-parser-options/index.md @@ -24,6 +24,7 @@ Options: ``` * `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`, you must pass `Future.class` and `0`. Use `GenericWrapper.withTransformer` to also convert the value at runtime. If the transformer returns `null`, the field is `null`. + Since 15.0.0, if the transformer returns a future of the wrapper's content, such as Reactor's `Mono::toFuture`, register it with `GenericWrapper.withCompletionStageTransformer(Mono.class, 0, Mono::toFuture)` instead. A future declared inside the wrapper, like `Mono>`, is then waited on too. With `withTransformer`, graphql-java gets that inner future as the value. Wrappers and futures nested in lists or in other wrappers are unwrapped too, e.g. `List>` or `List>`. If one element fails, the whole field fails. 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. From 19005415e6c742029ec1aded5374b196693db798 Mon Sep 17 00:00:00 2001 From: Oryan Date: Tue, 3 Nov 2026 15:09:31 -0500 Subject: [PATCH 2/2] Drop version mentions from the schema parser options --- content/tools/schema-parser-options/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/tools/schema-parser-options/index.md b/content/tools/schema-parser-options/index.md index 5d3efb0..3dca517 100644 --- a/content/tools/schema-parser-options/index.md +++ b/content/tools/schema-parser-options/index.md @@ -24,7 +24,7 @@ Options: ``` * `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`, you must pass `Future.class` and `0`. Use `GenericWrapper.withTransformer` to also convert the value at runtime. If the transformer returns `null`, the field is `null`. - Since 15.0.0, if the transformer returns a future of the wrapper's content, such as Reactor's `Mono::toFuture`, register it with `GenericWrapper.withCompletionStageTransformer(Mono.class, 0, Mono::toFuture)` instead. A future declared inside the wrapper, like `Mono>`, is then waited on too. With `withTransformer`, graphql-java gets that inner future as the value. + If the transformer returns a future of the wrapper's content, such as Reactor's `Mono::toFuture`, register it with `GenericWrapper.withCompletionStageTransformer(Mono.class, 0, Mono::toFuture)` instead. A future declared inside the wrapper, like `Mono>`, is then waited on too. With `withTransformer`, graphql-java gets that inner future as the value. Wrappers and futures nested in lists or in other wrappers are unwrapped too, e.g. `List>` or `List>`. If one element fails, the whole field fails. 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. @@ -33,7 +33,7 @@ Options: * `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. * `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`: The Jackson `ObjectMapper` that converts the arguments of method resolvers. Since 15.0.0 it's Jackson 3 (`tools.jackson`). +* `objectMapperConfigurer` / `objectMapperProvider`: The Jackson `ObjectMapper` that converts the arguments of method resolvers. It's a Jackson 3 mapper (`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`.