21.0
We are pleased to announce the release of graphql-java v21.0. This is a breaking change release.
Thanks to everyone in the community who contributed to the release, whether that was code, helping to report issues, or participating in discussions.
And Happy 8th Birthday to graphql-java, who celebrated their birthday last week!
Breaking Changes
Upgraded to Java 11
graphql-java now requires Java 11 as a minimum version. See the blog announcing the change.
For those who need time to upgrade to Java 11, keep in mind we will support graphql-java 20.x (with Java 8) for a short period as per our release policy.
If you are wondering why we are not on a later version, graphql-java has always been conservative on its base JVM version to allow the widest possible set of consumers.
Reverted stricter scalar parseValue
coercion, added monitoring and interceptor callback
v20.0 introduced a stricter set of scalar parseValue
coercions - for example previously an Integer
would accept a string if it parsed into a number but that was removed and a more strict system was put in place.
While technically more correct, and consistent with the graphql-js reference implementation, in practice this proved problematic for some consumers. So this more stricter parseValue
coercion was reverted in v20.3.
We would like to re-introduce this more strict scalar parseValue
conversion in the future and to that end we have introduced a graphql.execution.values.InputInterceptor
callback that allows you to observe what values you are receiving and potentially do special tweaking of those values.
A graphql.execution.values.legacycoercing.LegacyCoercingInputInterceptor
implementation will convert old less strict values into then more strict values for example.
If you had problems with scalar values we urge you to use the new InputInterceptor
to learn what less strict values are coming into your systems and fix them up. That way, when a future version re-introduces the more strict (and more correct) coercion then you will be prepared.
Static recordLike() methods no longer supported
In v20, the PropertyDataFetcher
would read property values from recordLike()
methods on objects even if they were static methods. This caused problems for some users and after considering how to fix it and talking to some our major consumers like the Spring team, we decided to remove this behavior. On balance we think this will lead to a better outcome over the long term.
This is a breaking change for those who might have relied on a static recordLike()
method being called for a property.
Removal of old deprecated methods and classes
The following PRs removed old deprecated methods and class. The changes are breaking ones but these have been deprecated for a long time.
Other small breaking changes
A very minor breaking change is that graphql.execution.ExecutionStrategy
had a protected method protected Iterable<Object> toIterable(Object result)
which really is a utility method and not designed for overriding. graphql.util.FpKit#toIterable
is the preferred replacement.
What's new in v21
ExecutableNormalisedXXX is now public API
The graphql.normalized.ExecutableNormalizedOperation
and graphql.normalized.ExecutableNormalizedField
code is now public API.
This API allows you to represent what MAY be executed given a schema and a valid GraphQL query.
This code is not intended for general consumption but perhaps you are writing a framework based on graphql-java and need to have a powerful representation of what would be executed, then these classes are for you.
This allows you to write specialized code (such as a new execution engine or perhaps a federated GraphQL engine like say Nadel) based on these tree like representations of a normalized and executable query.
Building extensions in data fetchers
There is a new graphql.extensions.ExtensionsBuilder
that allows data fetcher callbacks to add extension values into the final result. Since extensions are a map and there could be merge conflicts on values, a graphql.extensions.ExtensionsMerger
interface is provided to handle these conflicts and a default graphql.extensions.DefaultExtensionsMerger
is provided.
This is available via the graphql.GraphQLContext
and is put in there by default so data fetchers can rely on it being present. At the end of the request the ExtensionsBuilder
is called to build out a final map of extensions which is placed in the graphql.ExecutionResult
.
A smarter schema visitor API
A new graphql.schema.visitor.GraphQLSchemaVisitor
has been created that is more domain specific around visiting GraphQL schemas. The old graphql.schema.GraphQLTypeVisitor
worked however it is very generic in nature and is not domain specific to schemas.
The new API improves how you can visit schemas and the callbacks have better schema domain information provided on them. Also the graphql.schema.visitor.GraphQLSchemaVisitorEnvironment
is better than older alternative with clearer return methods like changeNode()
or deleteNode()
and so on for controlling how the visitor works.
This is an adaptor to GraphQLTypeVisitor
and hence can be used by the existing graphql.schema.SchemaTraverser
and graphql.schema.SchemaTransformer
classes (which expect a GraphQLTypeVisitor
) via a small call to graphql.schema.visitor.GraphQLSchemaVisitor#toTypeVisitor
.
Performance improvements
As always, we have tried to include some performance improvements in the release. One area of note is avoiding unnecessary CompletableFuture allocations when they are not needed.
Other things
The QueryComplexity calculator has been broken out into its own class and can be used outside the original graphql.analysis.MaxQueryComplexityInstrumentation
context.
The graphql.execution.DataFetcherResult#map
method was added to allow better functional mapping of results.
All Changes
- Correct diff when argument is "moved" and the type is changed by @gnawf in #3156
- Check for default value changes by @gnawf in #3157
- Bump com.google.guava:guava from 31.0.1-jre to 31.1-jre by @dependabot in #3134
- Bump biz.aQute.bnd.builder from 6.3.1 to 6.4.0 by @dependabot in #3135
- Better javadoc on how code is found during SchemaGeneration by @bbakerman in #3162
- Fix edge case with bad argument renamed by @gnawf in #3164
- Bump actions/setup-java from 1 to 3 by @dependabot in #3124
- Upgrade to Java 11 (round 2) by @dondonz in #3165
- Bump com.github.javafaker:javafaker from 0.13 to 1.0.2 by @dependabot in #3167
- cleanup schema diffing code, add comments by @andimarek in #3170
- upgrade to gradle 8.0.2 by @andimarek in #3171
- Bump io.github.gradle-nexus.publish-plugin from 1.1.0 to 1.3.0 by @dependabot in #3137
- Bump com.github.johnrengelman.shadow from 7.1.2 to 8.1.1 by @dependabot in #3152
- Bump org.testng:testng from 6.1.1 to 7.7.1 by @dependabot in #3127
- Remove long deprecated method by @dondonz in #3092
- Bump org.awaitility:awaitility-groovy from 3.1.6 to 4.2.0 by @dependabot in #3166
- Bump org.openjdk.jmh:jmh-core from 1.35 to 1.36 by @dependabot in #3178
- Bump com.fasterxml.jackson.core:jackson-databind from 2.13.1 to 2.14.2 by @dependabot in #3179
- Bump com.google.code.gson:gson from 2.8.9 to 2.10.1 by @dependabot in #3177
- Fix description changes causing renames by @gnawf in #3182
- Bump org.openjdk.jmh:jmh-generator-annprocess from 1.35 to 1.36 by @dependabot in #3176
- The ability to get query directives in ENF land by @bbakerman in #3048
- Allow DataFetcherResult to set extension values during execution by @bbakerman in #3123
- Bump org.eclipse.jetty:jetty-server from 9.4.26.v20200117 to 11.0.14 by @dependabot in #3180
- Revert stricter scalar parseValue coercion by @dondonz in #3186
- Bump org.eclipse.jetty:jetty-server from 11.0.14 to 11.0.15 by @dependabot in #3189
- Bump me.champeau.jmh from 0.7.0 to 0.7.1 by @dependabot in #3190
- improve schema diffing performance by @andimarek in #3172
- Schema diff optimizing by @andimarek in #3194
- schema diff: flip source and target graph depending on the isolated vertices by @andimarek in #3195
- This introduces an input interceptor by @bbakerman in #3188
- Fixed test since scalar messages changed by @bbakerman in #3201
- Bump google-github-actions/auth from 1.0.0 to 1.1.0 by @dependabot in #3199
- Bump com.fasterxml.jackson.core:jackson-databind from 2.14.2 to 2.15.0 by @dependabot in #3198
- More Schema diff work by @andimarek in #3200
- Sort diff edits before analysis by @gnawf in #3204
- Restrict parent changes by @gnawf in #3205
- Add map function to DataFetcherResult by @konnik in #3206
- This makes the ENF code public API by @bbakerman in #3185
- Bump google-github-actions/auth from 1.1.0 to 1.1.1 by @dependabot in #3214
- Adding in Java 9+ support for lookup across class loaders by @bbakerman in #3219
- Deprecate FieldsContainer on code registry by @bbakerman in #3211
- Bump org.testng:testng from 7.7.1 to 7.8.0 by @dependabot in #3224
- Bump com.fasterxml.jackson.core:jackson-databind from 2.15.0 to 2.15.1 by @dependabot in #3225
- LegacyCoercing support by @bbakerman in #3218
- Allow pluggable conditional node support by @bbakerman in #3223
- Smarter schema visitor by @bbakerman in #3087
- Bump com.google.guava:guava from 31.1-jre to 32.0.0-jre by @dependabot in #3234
- Dropping some CompletableFuture allocations by @dfa1 in #3233
- Removing the deprecated DataFetcherExceptionHandler sync method by @bbakerman in #3232
- Minor performance fixes by @dfa1 in #3236
- Bump com.fasterxml.jackson.core:jackson-databind from 2.15.1 to 2.15.2 by @dependabot in #3240
- Improve ENF isConditional by @gnawf in #3241
- Java doc fixups and some renaming by @bbakerman in #3242
- This avoids a CF allocation on data fetcher in the main case where there is no exception by @bbakerman in #3235
- Removing the deprecated CacheControl support by @bbakerman in #3231
- Bump com.google.guava:guava from 32.0.0-jre to 32.0.1-jre by @dependabot in #3248
- Breaking out query complexity into its own class by @bbakerman in #3254
- Bump com.google.guava:guava from 32.0.1-jre to 32.1.1-jre by @dependabot in #3258
- Bump org.codehaus.groovy:groovy-json from 3.0.17 to 3.0.18 by @dependabot in #3259
- Bump org.codehaus.groovy:groovy from 3.0.17 to 3.0.18 by @dependabot in #3260
- fixes when instrumentExecutionResult on AbortExecutionException by @bbakerman in #3262
- Adding builder for QueryDirectives by @bbakerman in #3261
New Contributors
Full Changelog: v20.2...v21.0