Upgrade to GraphQL Java 22.2

This also documents the new subscription ordering feature as reported
and requested in #949.

Closes gh-1044
This commit is contained in:
Brian Clozel
2024-08-21 18:10:01 +02:00
parent 311531b74f
commit 1979e435c3
5 changed files with 122 additions and 15 deletions

View File

@@ -3,7 +3,7 @@ description = "Spring for GraphQL"
ext {
moduleProjects = [project(":spring-graphql"), project(":spring-graphql-test")]
springFrameworkVersion = "6.1.11"
graphQlJavaVersion = "22.1"
graphQlJavaVersion = "22.2"
springBootVersion = "3.3.0"
}

View File

@@ -28,19 +28,7 @@ and `DataFetcherExceptionResolver` and `SubscriptionExceptionResolver` beans fo
xref:request-execution.adoc#execution.exceptions[exception resolution]. For further customizations, you can also
declare a `GraphQlSourceBuilderCustomizer` bean, for example:
[source,java,indent=0,subs="verbatim,quotes"]
----
@Configuration(proxyBeanMethods = false)
class GraphQlConfig {
@Bean
public GraphQlSourceBuilderCustomizer sourceBuilderCustomizer() {
return (builder) ->
builder.configureGraphQl(graphQlBuilder ->
graphQlBuilder.executionIdProvider(new CustomExecutionIdProvider()));
}
}
----
include-code::GraphQlConfig[]
@@ -409,7 +397,7 @@ request is simple enough and did not require asynchronous data fetching.
[[execution.reactive-datafetcher]]
[[execution.reactivedatafetcher]]
== Reactive `DataFetcher`
The default `GraphQlSource` builder enables support for a `DataFetcher` to return `Mono`
@@ -422,6 +410,15 @@ A reactive `DataFetcher` can rely on access to Reactor context propagated from t
transport layer, such as from a WebFlux request handling, see
xref:request-execution.adoc#execution.context.webflux[WebFlux Context].
In the case of subscription requests, GraphQL Java will produce items as soon as they
are available and all their requested fields were fetched. Because this involves several
layers of asynchronous data fetching, items might be sent over the wire out of their
original order. If you wish GraphQL Java to buffer items and retain the original order,
you can do so by setting the `SubscriptionExecutionStrategy.KEEP_SUBSCRIPTION_EVENTS_ORDERED`
configuration flag in the `GraphQLContext`. This can be done, for example, with a custom
`Instrumentation`:
include-code::GraphQlConfig[]
[[execution.context]]

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.graphql.docs.execution.graphqlsource;
import graphql.execution.ExecutionId;
import graphql.execution.ExecutionIdProvider;
class CustomExecutionIdProvider implements ExecutionIdProvider {
@Override
public ExecutionId provide(String query, String operationName, Object context) {
return null;
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.graphql.docs.execution.graphqlsource;
import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class GraphQlConfig {
@Bean
public GraphQlSourceBuilderCustomizer sourceBuilderCustomizer() {
return (builder) ->
builder.configureGraphQl((graphQlBuilder) ->
graphQlBuilder.executionIdProvider(new CustomExecutionIdProvider()));
}
}

View File

@@ -0,0 +1,50 @@
/*
* Copyright 2020-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.graphql.docs.execution.reactivedatafetcher;
import graphql.ExecutionResult;
import graphql.execution.SubscriptionExecutionStrategy;
import graphql.execution.instrumentation.InstrumentationContext;
import graphql.execution.instrumentation.InstrumentationState;
import graphql.execution.instrumentation.SimpleInstrumentationContext;
import graphql.execution.instrumentation.SimplePerformantInstrumentation;
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false)
public class GraphQlConfig {
@Bean
public SubscriptionOrderInstrumentation subscriptionOrderInstrumentation() {
return new SubscriptionOrderInstrumentation();
}
static class SubscriptionOrderInstrumentation extends SimplePerformantInstrumentation {
@Override
public InstrumentationContext<ExecutionResult> beginExecution(InstrumentationExecutionParameters parameters,
InstrumentationState state) {
// Enable option for keeping subscription results in upstream order
parameters.getGraphQLContext().put(SubscriptionExecutionStrategy.KEEP_SUBSCRIPTION_EVENTS_ORDERED, true);
return SimpleInstrumentationContext.noOp();
}
}
}