EXPEDIA GROUP TECHNOLOGY — ENGINEERING

GraphQL Kotlin 6.0.0 Release

Apollo Federation 2 support, batch request optimizations, Automatic Persisted Queries support and more

Samuel Vazquez
Expedia Group Technology

--

GraphQL Kotlin is a collection of libraries built on top of GraphQL Java that simplifies running GraphQL clients and servers in Kotlin.

The last major release 5.0.0 was on Sep 2021, and now we are happy to announce the 6.0.0 release.

Complete release notes can be found here.

Major changes and features

Apollo Federation 2 support

Federation v2 is an evolution of the Federation spec to make it more powerful, flexible and easier to adapt. While v1 and v2 schemas are similar in many ways, Federation v2 relaxes some of the constraints and adds additional capabilities. See Apollo documentation for details, and our documentation to enable Federation v2 schema generation.

Automatic coroutine context propagation

GraphQL Kotlin provides built-in support of coroutines in data fetchers or resolvers. In an attempt to standardize how we can propagate the CoroutineContext created by graphql-kotlin-server, users can now customize the coroutine context by providing a CoroutineContext::class entry in the GraphQLContext using GraphQLContextFactory.
See #1459 for details and our documentation.

Argument deserialization no longer relies on Jackson

DataFetcher argument parsing logic no longer depends on Jackson. Old logic was problematic as arguments passed to data fetchers were already coerced to the appropriate type by graphql-java, but since Jackson was unaware of it, it was resulting in a duplicate deserialization. This caused custom scalar inputs to have deserialization problems. See #1379 for details.

Update to GraphQL Java 18

Adds support for applied schema directive. In previous versions, GraphQLDirective represented both a schema definition object as well as individual instances that were applied to a schema or query element. Schema generation logic was updated to continue generating GraphQLDirective schema definitions and then create a corresponding instance of GraphQLAppliedDirective that is applied to a target element.
See #1393 for details.

Automatic Persisted Queries (APQ)

APQ is a technique created by Apollo to improve GraphQL network performance with zero build-time configuration by sending smaller GraphQL HTTP requests, a smaller request payload reduces bandwidth utilization and speeds up GraphQL client loading times.
A persisted query is a parsed and validated query document that is cached on the GraphQL Kotlin server, along with a unique identifier (SHA-256 hash). This way clients can send this identifier instead of the corresponding query which will drastically reduce the request size.
See the server documentation for additional details of usage.

GraphQL batch HTTP requests

GraphQL Kotlin servers can now execute batch operations concurrently, where before it was doing batch operations sequentially. This allows a client to send a list of GraphQL operations in a single batch HTTP request, and the overall response time will now be the time that slowest GraphQL operation in the batch took to resolve.

Sequential execution sequence diagram
Concurrent execution sequence diagram

New instrumentation instances use DataLoaders on multiple GraphQL Operations

With more and more GraphQL clients relying on batch HTTP requests to a GraphQL server to reduce network round trips, it was important to persist batching and deduplication of data fetchers or resolvers across all operations in the batch.

With that in mind, we added a custom set of instrumentation instances that will calculate when it is the right moment to dispatch a DataLoaderRegistry:

  1. DataLoaderLevelDispatchedInstrumentation: will dispatch all data loaders when a certain level across all GraphQL operations in a batch has been dispatched.
  2. DataLoaderSyncExecutionExhaustedInstrumentation: the most optimal time to dispatch all data loaders is when all possible synchronous execution paths across all GraphQL operations in a batch were exhausted.

With these instrumentation implementations, we can maximize the data fetching logic by applying batching, caching, and deduplication of data fetchers across single and batch GraphQL operations.

Regular instrumentation implementations apply to a single ExecutionInput or GraphQL Operation, whereas these custom implementations apply to multiple GraphQL operations (say a BatchRequest) and store their state in the GraphQLContext, allowing batching and deduplication of transactions across those multiple GraphQL operations.

Check out our documentation to see various examples and how easily these new instrumentation implementations can be enabled.

Further reading

For additional details on how to use the library please check out our previous GraphQL Kotlin stories ([1], [2], [3], [4]), examples and the documentation available on GitHub pages.

We are also open for feedback so please start a discussion or raise an issue for any new features you would like to see!

Thanks to graphql-kotlin maintainer Dariusz Kuc for assistance with this announcement.

--

--