@@ -8,8 +8,8 @@ use hyper::{
88 Body , Method , Request , Response , StatusCode ,
99} ;
1010use juniper:: {
11- http:: GraphQLRequest as JuniperGraphQLRequest , serde :: Deserialize , DefaultScalarValue ,
12- GraphQLType , GraphQLTypeAsync , InputValue , RootNode , ScalarValue ,
11+ http:: { GraphQLBatchRequest , GraphQLRequest as JuniperGraphQLRequest } ,
12+ GraphQLSubscriptionType , GraphQLType , GraphQLTypeAsync , InputValue , RootNode , ScalarValue ,
1313} ;
1414use serde_json:: error:: Error as SerdeError ;
1515use std:: { error:: Error , fmt, string:: FromUtf8Error , sync:: Arc } ;
6161 CtxT : Send + Sync + ' static ,
6262 QueryT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync + ' static ,
6363 MutationT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync + ' static ,
64- SubscriptionT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync + ' static ,
64+ SubscriptionT : GraphQLSubscriptionType < S , Context = CtxT > + Send + Sync ,
6565 QueryT :: TypeInfo : Send + Sync ,
6666 MutationT :: TypeInfo : Send + Sync ,
6767 SubscriptionT :: TypeInfo : Send + Sync ,
@@ -89,10 +89,10 @@ where
8989
9090fn parse_get_req < S : ScalarValue > (
9191 req : Request < Body > ,
92- ) -> Result < GraphQLRequest < S > , GraphQLRequestError > {
92+ ) -> Result < GraphQLBatchRequest < S > , GraphQLRequestError > {
9393 req. uri ( )
9494 . query ( )
95- . map ( |q| gql_request_from_get ( q) . map ( GraphQLRequest :: Single ) )
95+ . map ( |q| gql_request_from_get ( q) . map ( GraphQLBatchRequest :: Single ) )
9696 . unwrap_or_else ( || {
9797 Err ( GraphQLRequestError :: Invalid (
9898 "'query' parameter is missing" . to_string ( ) ,
@@ -102,15 +102,16 @@ fn parse_get_req<S: ScalarValue>(
102102
103103async fn parse_post_req < S : ScalarValue > (
104104 body : Body ,
105- ) -> Result < GraphQLRequest < S > , GraphQLRequestError > {
105+ ) -> Result < GraphQLBatchRequest < S > , GraphQLRequestError > {
106106 let chunk = hyper:: body:: to_bytes ( body)
107107 . await
108108 . map_err ( GraphQLRequestError :: BodyHyper ) ?;
109109
110110 let input = String :: from_utf8 ( chunk. iter ( ) . cloned ( ) . collect ( ) )
111111 . map_err ( GraphQLRequestError :: BodyUtf8 ) ?;
112112
113- serde_json:: from_str :: < GraphQLRequest < S > > ( & input) . map_err ( GraphQLRequestError :: BodyJSONError )
113+ serde_json:: from_str :: < GraphQLBatchRequest < S > > ( & input)
114+ . map_err ( GraphQLRequestError :: BodyJSONError )
114115}
115116
116117pub async fn graphiql ( graphql_endpoint : & str ) -> Result < Response < Body > , hyper:: Error > {
@@ -142,7 +143,7 @@ fn render_error(err: GraphQLRequestError) -> Response<Body> {
142143async fn execute_request < CtxT , QueryT , MutationT , SubscriptionT , S > (
143144 root_node : Arc < RootNode < ' static , QueryT , MutationT , SubscriptionT , S > > ,
144145 context : Arc < CtxT > ,
145- request : GraphQLRequest < S > ,
146+ request : GraphQLBatchRequest < S > ,
146147) -> Response < Body >
147148where
148149 S : ScalarValue + Send + Sync + ' static ,
@@ -154,8 +155,9 @@ where
154155 MutationT :: TypeInfo : Send + Sync ,
155156 SubscriptionT :: TypeInfo : Send + Sync ,
156157{
157- let ( is_ok, body) = request. execute_sync ( root_node, context) ;
158- let code = if is_ok {
158+ let res = request. execute_sync ( & * root_node, & context) ;
159+ let body = Body :: from ( serde_json:: to_string_pretty ( & res) . unwrap ( ) ) ;
160+ let code = if res. is_ok ( ) {
159161 StatusCode :: OK
160162 } else {
161163 StatusCode :: BAD_REQUEST
@@ -172,20 +174,21 @@ where
172174async fn execute_request_async < CtxT , QueryT , MutationT , SubscriptionT , S > (
173175 root_node : Arc < RootNode < ' static , QueryT , MutationT , SubscriptionT , S > > ,
174176 context : Arc < CtxT > ,
175- request : GraphQLRequest < S > ,
177+ request : GraphQLBatchRequest < S > ,
176178) -> Response < Body >
177179where
178180 S : ScalarValue + Send + Sync + ' static ,
179181 CtxT : Send + Sync + ' static ,
180182 QueryT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync + ' static ,
181183 MutationT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync + ' static ,
182- SubscriptionT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync + ' static ,
184+ SubscriptionT : GraphQLSubscriptionType < S , Context = CtxT > + Send + Sync ,
183185 QueryT :: TypeInfo : Send + Sync ,
184186 MutationT :: TypeInfo : Send + Sync ,
185187 SubscriptionT :: TypeInfo : Send + Sync ,
186188{
187- let ( is_ok, body) = request. execute ( root_node, context) . await ;
188- let code = if is_ok {
189+ let res = request. execute ( & * root_node, & context) . await ;
190+ let body = Body :: from ( serde_json:: to_string_pretty ( & res) . unwrap ( ) ) ;
191+ let code = if res. is_ok ( ) {
189192 StatusCode :: OK
190193 } else {
191194 StatusCode :: BAD_REQUEST
@@ -263,100 +266,6 @@ fn new_html_response(code: StatusCode) -> Response<Body> {
263266 resp
264267}
265268
266- #[ derive( serde_derive:: Deserialize ) ]
267- #[ serde( untagged) ]
268- #[ serde( bound = "InputValue<S>: Deserialize<'de>" ) ]
269- enum GraphQLRequest < S = DefaultScalarValue >
270- where
271- S : ScalarValue ,
272- {
273- Single ( JuniperGraphQLRequest < S > ) ,
274- Batch ( Vec < JuniperGraphQLRequest < S > > ) ,
275- }
276-
277- impl < S > GraphQLRequest < S >
278- where
279- S : ScalarValue ,
280- {
281- fn execute_sync < ' a , CtxT : ' a , QueryT , MutationT , SubscriptionT > (
282- self ,
283- root_node : Arc < RootNode < ' a , QueryT , MutationT , SubscriptionT , S > > ,
284- context : Arc < CtxT > ,
285- ) -> ( bool , hyper:: Body )
286- where
287- S : ' a + Send + Sync ,
288- QueryT : GraphQLType < S , Context = CtxT > + ' a ,
289- MutationT : GraphQLType < S , Context = CtxT > + ' a ,
290- SubscriptionT : GraphQLType < S , Context = CtxT > + ' a ,
291- {
292- match self {
293- GraphQLRequest :: Single ( request) => {
294- let res = request. execute_sync ( & root_node, & context) ;
295- let is_ok = res. is_ok ( ) ;
296- let body = Body :: from ( serde_json:: to_string_pretty ( & res) . unwrap ( ) ) ;
297- ( is_ok, body)
298- }
299- GraphQLRequest :: Batch ( requests) => {
300- let results: Vec < _ > = requests
301- . into_iter ( )
302- . map ( move |request| {
303- let root_node = root_node. clone ( ) ;
304- let res = request. execute_sync ( & root_node, & context) ;
305- let is_ok = res. is_ok ( ) ;
306- let body = serde_json:: to_string_pretty ( & res) . unwrap ( ) ;
307- ( is_ok, body)
308- } )
309- . collect ( ) ;
310-
311- let is_ok = !results. iter ( ) . any ( |& ( is_ok, _) | !is_ok) ;
312- let bodies: Vec < _ > = results. into_iter ( ) . map ( |( _, body) | body) . collect ( ) ;
313- let body = hyper:: Body :: from ( format ! ( "[{}]" , bodies. join( "," ) ) ) ;
314- ( is_ok, body)
315- }
316- }
317- }
318-
319- async fn execute < ' a , CtxT : ' a , QueryT , MutationT , SubscriptionT > (
320- self ,
321- root_node : Arc < RootNode < ' a , QueryT , MutationT , SubscriptionT , S > > ,
322- context : Arc < CtxT > ,
323- ) -> ( bool , hyper:: Body )
324- where
325- S : Send + Sync ,
326- QueryT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync ,
327- MutationT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync ,
328- SubscriptionT : GraphQLTypeAsync < S , Context = CtxT > + Send + Sync ,
329- QueryT :: TypeInfo : Send + Sync ,
330- MutationT :: TypeInfo : Send + Sync ,
331- SubscriptionT :: TypeInfo : Send + Sync ,
332- CtxT : Send + Sync ,
333- {
334- match self {
335- GraphQLRequest :: Single ( request) => {
336- let res = request. execute ( & * root_node, & context) . await ;
337- let is_ok = res. is_ok ( ) ;
338- let body = Body :: from ( serde_json:: to_string_pretty ( & res) . unwrap ( ) ) ;
339- ( is_ok, body)
340- }
341- GraphQLRequest :: Batch ( requests) => {
342- let futures = requests
343- . iter ( )
344- . map ( |request| request. execute ( & * root_node, & context) )
345- . collect :: < Vec < _ > > ( ) ;
346- let results = futures:: future:: join_all ( futures) . await ;
347-
348- let is_ok = results. iter ( ) . all ( |res| res. is_ok ( ) ) ;
349- let bodies: Vec < _ > = results
350- . into_iter ( )
351- . map ( |res| serde_json:: to_string_pretty ( & res) . unwrap ( ) )
352- . collect ( ) ;
353- let body = hyper:: Body :: from ( format ! ( "[{}]" , bodies. join( "," ) ) ) ;
354- ( is_ok, body)
355- }
356- }
357- }
358- }
359-
360269#[ derive( Debug ) ]
361270enum GraphQLRequestError {
362271 BodyHyper ( hyper:: Error ) ,
0 commit comments