22
33import com .fasterxml .jackson .core .JsonProcessingException ;
44import com .fasterxml .jackson .databind .ObjectMapper ;
5+ import com .google .common .collect .ImmutableMap ;
56import graphql .DeferredExecutionResult ;
67import graphql .ExecutionInput ;
78import graphql .ExecutionResult ;
1718import org .springframework .web .bind .annotation .RequestBody ;
1819import org .springframework .web .bind .annotation .RequestMapping ;
1920import org .springframework .web .bind .annotation .RequestMethod ;
20- import org .springframework .web .bind .annotation .ResponseBody ;
2121import org .springframework .web .bind .annotation .RestController ;
2222
23+ import javax .servlet .AsyncContext ;
24+ import javax .servlet .http .HttpServletRequest ;
2325import javax .servlet .http .HttpServletResponse ;
2426import java .io .IOException ;
2527import java .io .PrintWriter ;
@@ -31,6 +33,7 @@ public class GraphQLController {
3133
3234
3335 public static final String CRLF = "\r \n " ;
36+
3437 @ Autowired
3538 GraphQL graphql ;
3639
@@ -40,11 +43,16 @@ public class GraphQLController {
4043
4144 Logger log = LoggerFactory .getLogger (GraphQLController .class );
4245
46+ @ RequestMapping (value = "/test" , method = RequestMethod .GET , produces = MediaType .APPLICATION_JSON_VALUE )
47+ @ CrossOrigin
48+ public void graphql (HttpServletRequest httpServletRequest , HttpServletResponse httpServletResponse ) throws IOException {
49+ ImmutableMap <String , Object > body = ImmutableMap .of ("query" , "{books{title author comments @defer {user text}}}" );
50+ graphql (body , httpServletRequest , httpServletResponse );
51+ }
4352
4453 @ RequestMapping (value = "/graphql" , method = RequestMethod .POST , produces = MediaType .APPLICATION_JSON_VALUE )
45- @ ResponseBody
4654 @ CrossOrigin
47- public void graphql (@ RequestBody Map <String , Object > body , HttpServletResponse httpServletResponse ) throws IOException {
55+ public void graphql (@ RequestBody Map <String , Object > body , HttpServletRequest httpServletRequest , HttpServletResponse httpServletResponse ) throws IOException {
4856 String query = (String ) body .get ("query" );
4957 if (query == null ) {
5058 query = "" ;
@@ -61,14 +69,29 @@ public void graphql(@RequestBody Map<String, Object> body, HttpServletResponse h
6169 ExecutionResult executionResult = graphql .execute (executionInput );
6270 Map <Object , Object > extensions = executionResult .getExtensions ();
6371 if (extensions != null && extensions .containsKey (GraphQL .DEFERRED_RESULTS )) {
64- Publisher <DeferredExecutionResult > deferredResults = (Publisher <DeferredExecutionResult >) extensions .get (GraphQL .DEFERRED_RESULTS );
65- sendDeferResponse (httpServletResponse , executionResult , deferredResults );
72+ handleDeferResponse (httpServletRequest , httpServletResponse , executionResult , extensions );
6673 } else {
67- sendNormalResponse (httpServletResponse , executionResult );
74+ handleNormalResponse (httpServletResponse , executionResult );
6875 }
6976 }
7077
71- private void sendNormalResponse (HttpServletResponse httpServletResponse , ExecutionResult executionResult ) throws IOException {
78+ private void handleDeferResponse (HttpServletRequest httpServletRequest ,
79+ HttpServletResponse httpServletResponse ,
80+ ExecutionResult executionResult ,
81+ Map <Object , Object > extensions ) {
82+ AsyncContext asyncContext = httpServletRequest .startAsync ();
83+ asyncContext .start (() -> {
84+ Publisher <DeferredExecutionResult > deferredResults = (Publisher <DeferredExecutionResult >) extensions .get (GraphQL .DEFERRED_RESULTS );
85+ try {
86+ sendDeferResponse (asyncContext , httpServletRequest , httpServletResponse , executionResult , deferredResults );
87+ } catch (IOException e ) {
88+ e .printStackTrace ();
89+ }
90+ });
91+
92+ }
93+
94+ private void handleNormalResponse (HttpServletResponse httpServletResponse , ExecutionResult executionResult ) throws IOException {
7295 Map <String , Object > result = executionResult .toSpecification ();
7396 httpServletResponse .setStatus (HttpServletResponse .SC_OK );
7497 httpServletResponse .setCharacterEncoding ("UTF-8" );
@@ -81,7 +104,7 @@ private void sendNormalResponse(HttpServletResponse httpServletResponse, Executi
81104
82105 }
83106
84- private void sendDeferResponse (HttpServletResponse httpServletResponse , ExecutionResult executionResult , Publisher <DeferredExecutionResult > deferredResults ) throws IOException {
107+ private void sendDeferResponse (AsyncContext asyncContext , HttpServletRequest httpServletRequest , HttpServletResponse httpServletResponse , ExecutionResult executionResult , Publisher <DeferredExecutionResult > deferredResults ) throws IOException {
85108 httpServletResponse .setStatus (HttpServletResponse .SC_OK );
86109 httpServletResponse .setCharacterEncoding ("UTF-8" );
87110 httpServletResponse .setContentType ("multipart/mixed; boundary=\" -\" " );
@@ -90,11 +113,10 @@ private void sendDeferResponse(HttpServletResponse httpServletResponse, Executio
90113 httpServletResponse .setHeader ("Connection" , "keep-alive" );
91114 PrintWriter writer = httpServletResponse .getWriter ();
92115
93- writer .append (CRLF ).append ("---" ).append (CRLF );
94116 DeferPart deferPart = new DeferPart (executionResult .toSpecification ());
117+ writer .append (CRLF ).append ("---" ).append (CRLF );
95118 String body = deferPart .write ();
96119 writer .write (body );
97- writer .append (CRLF ).append ("---" ).append (CRLF );
98120 httpServletResponse .flushBuffer ();
99121
100122 deferredResults .subscribe (new Subscriber <DeferredExecutionResult >() {
@@ -112,8 +134,8 @@ public void onNext(DeferredExecutionResult executionResult) {
112134 try {
113135 DeferPart deferPart = new DeferPart (executionResult .toSpecification ());
114136 String body = deferPart .write ();
137+ writer .append (CRLF ).append ("---" ).append (CRLF );
115138 writer .write (body );
116- writer .append (CRLF ).append ("-----" ).append (CRLF );
117139 httpServletResponse .flushBuffer ();
118140 subscription .request (10 );
119141 } catch (Exception e ) {
@@ -128,7 +150,9 @@ public void onError(Throwable t) {
128150
129151 @ Override
130152 public void onComplete () {
153+ writer .append (CRLF ).append ("-----" ).append (CRLF );
131154 writer .close ();
155+ asyncContext .complete ();
132156 }
133157 });
134158
0 commit comments