Skip to content

Commit 518617d

Browse files
committed
Lenient adapt non-Publisher subscription result
Closes gh-1213
1 parent ce9472f commit 518617d

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

spring-graphql/src/main/java/org/springframework/graphql/execution/ReactiveAdapterRegistryHelper.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2024 the original author or authors.
2+
* Copyright 2002-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -25,7 +25,6 @@
2525

2626
import org.springframework.core.ReactiveAdapter;
2727
import org.springframework.core.ReactiveAdapterRegistry;
28-
import org.springframework.util.Assert;
2928

3029
/**
3130
* Helper to adapt a result Object to {@link Mono} or {@link Flux} through
@@ -90,7 +89,8 @@ public static Object toMonoOrFluxIfReactive(@Nullable Object result) {
9089

9190
/**
9291
* Return a {@link Flux} for the given result Object, adapting to a
93-
* {@link Publisher} first if necessary via {@link ReactiveAdapterRegistry}.
92+
* {@link Publisher} via {@link ReactiveAdapterRegistry} or wrapping it as
93+
* {@code Flux} if necessary.
9494
* @param result the result Object to adapt
9595
* @return a {@link Flux}, possibly empty if the result is {@code null}
9696
*/
@@ -102,8 +102,7 @@ public static Flux<?> toSubscriptionFlux(@Nullable Object result) {
102102
return Flux.from(publisher);
103103
}
104104
ReactiveAdapter adapter = registry.getAdapter(result.getClass());
105-
Assert.state(adapter != null, "Expected Publisher for a subscription");
106-
return Flux.from(adapter.toPublisher(result));
105+
return ((adapter != null) ? Flux.from(adapter.toPublisher(result)) : Flux.just(result));
107106
}
108107

109108
/**

spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlSseHandlerTests.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2024 the original author or authors.
2+
* Copyright 2020-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -104,6 +104,26 @@ void shouldWriteMultipleEventsForSubscription() {
104104
""");
105105
}
106106

107+
@Test // gh-1213
108+
void shouldHandleNonPublisherValue() {
109+
110+
SerializableGraphQlRequest request = initRequest(
111+
"subscription TestSubscription { bookSearch(author:\"Orwell\") { id name } }");
112+
113+
GraphQlSseHandler handler = createHandler(env -> BookSource.getBook(1L));
114+
MockServerHttpResponse response = handleRequest(this.httpRequest, handler, request);
115+
116+
assertThat(response.getHeaders().getContentType().isCompatibleWith(MediaType.TEXT_EVENT_STREAM)).isTrue();
117+
assertThat(response.getBodyAsString().block()).isEqualTo("""
118+
event:next
119+
data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}}
120+
121+
event:complete
122+
data:{}
123+
124+
""");
125+
}
126+
107127
@Test
108128
void shouldWriteEventsAndTerminalError() {
109129

spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlSseHandlerTests.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2020-2024 the original author or authors.
2+
* Copyright 2020-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -111,6 +111,25 @@ void shouldWriteMultipleEventsForSubscription() throws Exception {
111111
""");
112112
}
113113

114+
@Test // gh-1213
115+
void shouldHandleNonPublisherValue() throws Exception {
116+
GraphQlSseHandler handler = createSseHandler(env -> BookSource.getBook(1L));
117+
MockHttpServletRequest request = createServletRequest("""
118+
{ "query": "subscription TestSubscription { bookSearch { id name } }" }
119+
""");
120+
MockHttpServletResponse response = handleAndAwait(request, handler);
121+
122+
assertThat(response.getContentType()).isEqualTo(MediaType.TEXT_EVENT_STREAM_VALUE);
123+
assertThat(response.getContentAsString()).isEqualTo("""
124+
event:next
125+
data:{"data":{"bookSearch":{"id":"1","name":"Nineteen Eighty-Four"}}}
126+
127+
event:complete
128+
data:
129+
130+
""");
131+
}
132+
114133
@Test
115134
void shouldWriteEventsAndTerminalError() throws Exception {
116135

0 commit comments

Comments
 (0)