Skip to content

Commit afc4c49

Browse files
committed
Deferred results should always be deferred and be sent second
1 parent 110813b commit afc4c49

File tree

3 files changed

+62
-5
lines changed

3 files changed

+62
-5
lines changed

src/main/java/graphql/servlet/AbstractGraphQLHttpServlet.java

+1
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ private static class StaticDataPublisher<T> extends SingleSubscriberPublisher<T>
585585
StaticDataPublisher(T data) {
586586
super();
587587
super.offer(data);
588+
super.noMoreData();
588589
}
589590
}
590591

src/test/groovy/graphql/servlet/AbstractGraphQLHttpServletSpec.groovy

+35-5
Original file line numberDiff line numberDiff line change
@@ -1054,9 +1054,39 @@ class AbstractGraphQLHttpServletSpec extends Specification {
10541054

10551055
def "defer query over HTTP POST"() {
10561056
setup:
1057-
servlet = TestUtils.createDefaultServlet()
1057+
request.setContent('{"query": "subscription Subscription($arg: String!) { echo(arg: $arg) }", "operationName": "Subscription", "variables": {"arg": "test"}}'.bytes)
1058+
request.setAsyncSupported(true)
1059+
1060+
when:
1061+
servlet.doPost(request, response)
1062+
then:
1063+
response.getStatus() == STATUS_OK
1064+
response.getContentType() == CONTENT_TYPE_SERVER_SENT_EVENTS
1065+
1066+
when:
1067+
subscriptionLatch.await(1, TimeUnit.SECONDS)
1068+
then:
1069+
getSubscriptionResponseContent()[0].data.echo == "First\n\ntest"
1070+
getSubscriptionResponseContent()[1].data.echo == "Second\n\ntest"
1071+
}
1072+
1073+
def "deferred query that takes longer than initial results, should still be sent second"() {
1074+
setup:
1075+
servlet = TestUtils.createDefaultServlet({ env ->
1076+
if (env.getField().name == "a") {
1077+
Thread.sleep(1000)
1078+
}
1079+
env.arguments.arg
1080+
})
10581081
request.setContent(mapper.writeValueAsBytes([
1059-
query: 'query { echo(arg:"test") @defer }'
1082+
query: '''
1083+
{
1084+
object {
1085+
a(arg: "Hello")
1086+
b(arg: "World") @defer
1087+
}
1088+
}
1089+
'''
10601090
]))
10611091
request.setAsyncSupported(true)
10621092

@@ -1066,15 +1096,15 @@ class AbstractGraphQLHttpServletSpec extends Specification {
10661096
then:
10671097
response.getStatus() == STATUS_OK
10681098
response.getContentType() == CONTENT_TYPE_SERVER_SENT_EVENTS
1069-
getSubscriptionResponseContent()[0].data.echo == null
1099+
getSubscriptionResponseContent()[0].data.object.a == "Hello" // a has a Thread.sleep
10701100

10711101
when:
10721102
subscriptionLatch.await(1, TimeUnit.SECONDS)
10731103

10741104
then:
10751105
def content = getSubscriptionResponseContent()
1076-
content[1].data == "test"
1077-
content[1].path == ["echo"]
1106+
content[1].data == "World"
1107+
content[1].path == ["object", "b"]
10781108
}
10791109

10801110
def "errors before graphql schema execution return internal server error"() {

src/test/groovy/graphql/servlet/TestUtils.groovy

+26
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,32 @@ class TestUtils {
115115
}
116116
field.dataFetcher(queryDataFetcher)
117117
}
118+
.field { GraphQLFieldDefinition.Builder field ->
119+
field.name("object")
120+
field.type(
121+
GraphQLObjectType.newObject()
122+
.name("NestedObject")
123+
.field { nested ->
124+
nested.name("a")
125+
nested.type(Scalars.GraphQLString)
126+
nested.argument { argument ->
127+
argument.name("arg")
128+
argument.type(Scalars.GraphQLString)
129+
}
130+
nested.dataFetcher(queryDataFetcher)
131+
}
132+
.field { nested ->
133+
nested.name("b")
134+
nested.type(Scalars.GraphQLString)
135+
nested.argument { argument ->
136+
argument.name("arg")
137+
argument.type(Scalars.GraphQLString)
138+
}
139+
nested.dataFetcher(queryDataFetcher)
140+
}
141+
)
142+
field.dataFetcher(new StaticDataFetcher([:]))
143+
}
118144
.field { GraphQLFieldDefinition.Builder field ->
119145
field.name("returnsNullIncorrectly")
120146
field.type(new GraphQLNonNull(Scalars.GraphQLString))

0 commit comments

Comments
 (0)