Release 25.0 · graphql-java/graphql-java

Key changes

Dataloader

Refactoring strategy

The existing PerLevelDataLoaderStrategy has been refactored which lead to simplifications and performance improvements.

New strategies

Two new strategies were introduced: CHAINED and EXHAUSTED. Both can be configured via UnusalConfiguration (see next section).

CHAINED allow for chained DataLoaders to be used while keeping a per level dispatch strategies.

EXHAUSTED is a completely new strategy that works on the basis to dispatch once the engine is not busy. It mirrors the JS data loader dispatch strategy, but for a multi threaded system.

Unusual Configuration

A more generalised configuration mechanism has been added for "unusual configuration". By that we mean configuation we dont expect many people to use but if they do its now in a more common place

For example if you wanted to change the maximum depth the document parser will accept you could call the following methods.

        var parserOptions = newParserOptions().maxRuleDepth(99).build()
        GraphQL.unusualConfiguration().parsing().setDefaultParserOptions(parserOptions)

JSpecify Annotations

The team are starting to embrace https://jspecify.dev/ annotations as the way to indicate nullable and non nullable fields. Many important classes have had these annotations added to help make it more semantically clear when a value can be null or not.

Breaking Changes

A wrapping FetchedValue object is not always returned on field fetchers for performance reasons. This means that graphql.execution.instrumentation.parameters.InstrumentationFieldCompleteParameters#getFetchedObject was created to replace the older getFetchedValue method and the returns object can sometimes be a FetchedValue or sometimes a simple POJO value.

Performance improvements

A series of performance improvements have been made to reduce the memory footprint of the library. Also the Java .stream() operator can be slower than a more direct loop and many of these calls have been changed for performance reasons.

  • avoid wrapping materialized fieldValueObject in a CompletableFuture by @samuelAndalon in #3943
  • ExecutionStrategyParameters now has a direct transform without a Builder by @bbakerman in #3935
  • ExecutionStepInfo now has a direct transform without a Builder by @bbakerman in #3934
  • FpKit now longer uses streams for performance reasons by @bbakerman in #3932
  • Implement toString/hashCode/equals for DataFetcherResult by @AlexandreCarlton in #3964
  • Introduce a filter and map imperative method to replace .stream() calls by @bbakerman in #3931
  • Removing some of the Optional.map() and .stream() for performance reasons by @bbakerman in #3930
  • Stop creating NonNullableFieldValidator every for every object or list field by @bbakerman in #3929

What's Changed

New Contributors

Full Changelog: v23.0...v25.0