Skip to content
This repository was archived by the owner on Dec 19, 2023. It is now read-only.

Commit e0552aa

Browse files
authored
Merge pull request #514 from graphql-java-kickstart/feature/326-mono-support
Autoconfigure Generic wrapper for Mono fix #326
2 parents 1b730d3 + e5850d4 commit e0552aa

File tree

13 files changed

+203
-5
lines changed

13 files changed

+203
-5
lines changed

graphql-kickstart-spring-boot-autoconfigure-tools/src/main/java/graphql/kickstart/tools/boot/GraphQLJavaToolsAutoConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
@Slf4j
4545
@Configuration
4646
@ConditionalOnClass(SchemaParser.class)
47-
@AutoConfigureAfter({JacksonAutoConfiguration.class})
47+
@AutoConfigureAfter(JacksonAutoConfiguration.class)
4848
@EnableConfigurationProperties(GraphQLToolsProperties.class)
4949
public class GraphQLJavaToolsAutoConfiguration {
5050

graphql-kickstart-spring-boot-autoconfigure-webflux/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ dependencies {
55
implementation "org.springframework.boot:spring-boot-autoconfigure"
66
implementation "com.graphql-java-kickstart:graphql-java-kickstart:$LIB_GRAPHQL_SERVLET_VER"
77
implementation "org.springframework.boot:spring-boot-starter-webflux"
8+
9+
testImplementation "org.springframework.boot:spring-boot-starter-test"
10+
testImplementation(project(":graphql-kickstart-spring-boot-starter-tools"))
811
}

graphql-kickstart-spring-boot-autoconfigure-webflux/src/main/java/graphql/kickstart/spring/webflux/boot/GraphQLSpringWebfluxAutoConfiguration.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package graphql.kickstart.spring.webflux.boot;
22

33
import static graphql.kickstart.execution.GraphQLObjectMapper.newBuilder;
4+
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE;
45

56
import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentationOptions;
67
import graphql.kickstart.execution.BatchedDataLoaderGraphQLBuilder;
@@ -39,6 +40,7 @@
3940
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
4041
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
4142
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
43+
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
4244
import org.springframework.context.annotation.Bean;
4345
import org.springframework.context.annotation.Configuration;
4446
import org.springframework.context.annotation.Import;
@@ -50,8 +52,9 @@
5052
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
5153
@Slf4j
5254
@Configuration
53-
@ConditionalOnBean({GraphQLSchema.class})
54-
@AutoConfigureAfter({GraphQLJavaToolsAutoConfiguration.class})
55+
@ConditionalOnWebApplication(type = REACTIVE)
56+
@ConditionalOnBean(GraphQLSchema.class)
57+
@AutoConfigureAfter(GraphQLJavaToolsAutoConfiguration.class)
5558
@Import({GraphQLController.class, ReactiveWebSocketSubscriptionsHandler.class})
5659
public class GraphQLSpringWebfluxAutoConfiguration {
5760

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package graphql.kickstart.spring.webflux.boot;
2+
3+
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE;
4+
5+
import graphql.kickstart.tools.SchemaParser;
6+
import graphql.kickstart.tools.SchemaParserOptions.GenericWrapper;
7+
import graphql.kickstart.tools.boot.GraphQLJavaToolsAutoConfiguration;
8+
import java.util.List;
9+
import org.springframework.beans.factory.annotation.Autowired;
10+
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
11+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
12+
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
13+
import org.springframework.context.annotation.Bean;
14+
import org.springframework.context.annotation.Configuration;
15+
import reactor.core.publisher.Mono;
16+
17+
@Configuration
18+
@ConditionalOnClass(SchemaParser.class)
19+
@ConditionalOnWebApplication(type = REACTIVE)
20+
@AutoConfigureBefore(GraphQLJavaToolsAutoConfiguration.class)
21+
public class MonoAutoConfiguration {
22+
23+
@Bean
24+
GenericWrapper monoWrapper(@Autowired(required = false) List<GenericWrapper> genericWrappers) {
25+
if (notWrapsMono(genericWrappers)) {
26+
return GenericWrapper.withTransformer(
27+
Mono.class,
28+
0,
29+
Mono::toFuture,
30+
t -> t
31+
);
32+
}
33+
return null;
34+
}
35+
36+
private boolean notWrapsMono(List<GenericWrapper> genericWrappers) {
37+
return genericWrappers == null ||
38+
genericWrappers.stream().noneMatch(it -> it.getType().isAssignableFrom(Mono.class));
39+
}
40+
41+
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
2-
graphql.kickstart.spring.webflux.boot.GraphQLSpringWebfluxAutoConfiguration
2+
graphql.kickstart.spring.webflux.boot.GraphQLSpringWebfluxAutoConfiguration,\
3+
graphql.kickstart.spring.webflux.boot.MonoAutoConfiguration
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package graphql.kickstart.spring.webflux.boot;
2+
3+
import graphql.kickstart.tools.GraphQLQueryResolver;
4+
import org.springframework.stereotype.Component;
5+
import reactor.core.publisher.Mono;
6+
7+
@Component
8+
class HelloQuery implements GraphQLQueryResolver {
9+
10+
public Mono<String> hello() {
11+
return Mono.just("Hello world");
12+
}
13+
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package graphql.kickstart.spring.webflux.boot;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import lombok.RequiredArgsConstructor;
6+
import lombok.val;
7+
import org.json.JSONException;
8+
import org.json.JSONObject;
9+
import org.junit.jupiter.api.Test;
10+
import org.junit.jupiter.api.extension.ExtendWith;
11+
import org.springframework.beans.factory.annotation.Autowired;
12+
import org.springframework.boot.test.context.SpringBootTest;
13+
import org.springframework.http.MediaType;
14+
import org.springframework.test.context.junit.jupiter.SpringExtension;
15+
import org.springframework.test.web.reactive.server.WebTestClient;
16+
17+
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
18+
@RequiredArgsConstructor
19+
@ExtendWith(SpringExtension.class)
20+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
21+
class MonoAutoConfigurationTest {
22+
23+
@Autowired
24+
private WebTestClient webTestClient;
25+
26+
@Test
27+
void monoWrapper() throws JSONException {
28+
val result = webTestClient.post()
29+
.uri("/graphql")
30+
.contentType(MediaType.APPLICATION_JSON)
31+
.bodyValue("{ \"query\": \"query { hello } \"}")
32+
.exchange()
33+
.returnResult(String.class);
34+
val response = result.getResponseBody().blockFirst();
35+
val json = new JSONObject(response);
36+
assertThat(json.getJSONObject("data").get("hello")).isEqualTo("Hello world");
37+
}
38+
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package graphql.kickstart.spring.webflux.boot;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import graphql.kickstart.tools.SchemaParserOptions.GenericWrapper;
6+
import lombok.RequiredArgsConstructor;
7+
import lombok.val;
8+
import org.json.JSONException;
9+
import org.json.JSONObject;
10+
import org.junit.jupiter.api.Test;
11+
import org.junit.jupiter.api.extension.ExtendWith;
12+
import org.springframework.beans.factory.annotation.Autowired;
13+
import org.springframework.boot.test.context.SpringBootTest;
14+
import org.springframework.boot.test.context.TestConfiguration;
15+
import org.springframework.context.annotation.Bean;
16+
import org.springframework.http.MediaType;
17+
import org.springframework.test.context.junit.jupiter.SpringExtension;
18+
import org.springframework.test.web.reactive.server.WebTestClient;
19+
import reactor.core.publisher.Mono;
20+
21+
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
22+
@RequiredArgsConstructor
23+
@ExtendWith(SpringExtension.class)
24+
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
25+
class MonoGenericWrapperAlreadyDefinedTest {
26+
27+
@Autowired
28+
private WebTestClient webTestClient;
29+
30+
@Test
31+
void monoWrapper() throws JSONException {
32+
val result = webTestClient.post()
33+
.uri("/graphql")
34+
.contentType(MediaType.APPLICATION_JSON)
35+
.bodyValue("{ \"query\": \"query { hello } \"}")
36+
.exchange()
37+
.returnResult(String.class);
38+
val response = result.getResponseBody().blockFirst();
39+
val json = new JSONObject(response);
40+
assertThat(json.getJSONObject("data").get("hello")).isEqualTo("Hello world");
41+
}
42+
43+
@TestConfiguration
44+
static class MonoConfiguration {
45+
@Bean
46+
GenericWrapper genericWrapper() {
47+
return GenericWrapper.withTransformer(
48+
Mono.class,
49+
0,
50+
Mono::toFuture,
51+
t -> t
52+
);
53+
}
54+
}
55+
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package graphql.kickstart.spring.webflux.boot;
2+
3+
import graphql.kickstart.tools.GraphQLSubscriptionResolver;
4+
import graphql.schema.DataFetchingEnvironment;
5+
import java.time.Duration;
6+
import org.reactivestreams.Publisher;
7+
import org.springframework.stereotype.Service;
8+
import reactor.core.publisher.Flux;
9+
10+
@Service
11+
class MySubscriptionResolver implements GraphQLSubscriptionResolver {
12+
13+
Publisher<Integer> hello(DataFetchingEnvironment env) {
14+
return Flux.range(0, 100).delayElements(Duration.ofSeconds(1));
15+
}
16+
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package graphql.kickstart.spring.webflux.boot;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class WebfluxApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(WebfluxApplication.class, args);
11+
}
12+
13+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
query {
2+
hello
3+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type Query {
2+
hello: String
3+
}
4+
5+
type Subscription {
6+
hello: Int
7+
}

graphql-spring-boot-autoconfigure/src/main/java/graphql/kickstart/spring/web/boot/GraphQLWebAutoConfiguration.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
7373
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
7474
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
75+
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
7576
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
7677
import org.springframework.boot.context.properties.ConfigurationProperties;
7778
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -92,7 +93,7 @@
9293
@Slf4j
9394
@Configuration
9495
@RequiredArgsConstructor
95-
@ConditionalOnWebApplication
96+
@ConditionalOnWebApplication(type = Type.SERVLET)
9697
@ConditionalOnClass(DispatcherServlet.class)
9798
@Conditional(OnSchemaOrSchemaProviderBean.class)
9899
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")

0 commit comments

Comments
 (0)