From 6b040c509b85923537cddc467ac0aecde128e6f4 Mon Sep 17 00:00:00 2001 From: Christian Legnitto Date: Thu, 9 Apr 2020 22:45:34 -1000 Subject: [PATCH] Update juniper_hyper to central `GraphQLBatch*` enums (#613) --- juniper_hyper/src/lib.rs | 125 ++++++--------------------------------- 1 file changed, 17 insertions(+), 108 deletions(-) diff --git a/juniper_hyper/src/lib.rs b/juniper_hyper/src/lib.rs index 5e1adcd6..437f8d9f 100644 --- a/juniper_hyper/src/lib.rs +++ b/juniper_hyper/src/lib.rs @@ -8,8 +8,8 @@ use hyper::{ Body, Method, Request, Response, StatusCode, }; use juniper::{ - http::GraphQLRequest as JuniperGraphQLRequest, serde::Deserialize, DefaultScalarValue, - GraphQLType, GraphQLTypeAsync, InputValue, RootNode, ScalarValue, + http::{GraphQLBatchRequest, GraphQLRequest as JuniperGraphQLRequest}, + GraphQLSubscriptionType, GraphQLType, GraphQLTypeAsync, InputValue, RootNode, ScalarValue, }; use serde_json::error::Error as SerdeError; use std::{error::Error, fmt, string::FromUtf8Error, sync::Arc}; @@ -61,7 +61,7 @@ where CtxT: Send + Sync + 'static, QueryT: GraphQLTypeAsync + Send + Sync + 'static, MutationT: GraphQLTypeAsync + Send + Sync + 'static, - SubscriptionT: GraphQLTypeAsync + Send + Sync + 'static, + SubscriptionT: GraphQLSubscriptionType + Send + Sync, QueryT::TypeInfo: Send + Sync, MutationT::TypeInfo: Send + Sync, SubscriptionT::TypeInfo: Send + Sync, @@ -89,10 +89,10 @@ where fn parse_get_req( req: Request, -) -> Result, GraphQLRequestError> { +) -> Result, GraphQLRequestError> { req.uri() .query() - .map(|q| gql_request_from_get(q).map(GraphQLRequest::Single)) + .map(|q| gql_request_from_get(q).map(GraphQLBatchRequest::Single)) .unwrap_or_else(|| { Err(GraphQLRequestError::Invalid( "'query' parameter is missing".to_string(), @@ -102,7 +102,7 @@ fn parse_get_req( async fn parse_post_req( body: Body, -) -> Result, GraphQLRequestError> { +) -> Result, GraphQLRequestError> { let chunk = hyper::body::to_bytes(body) .await .map_err(GraphQLRequestError::BodyHyper)?; @@ -110,7 +110,8 @@ async fn parse_post_req( let input = String::from_utf8(chunk.iter().cloned().collect()) .map_err(GraphQLRequestError::BodyUtf8)?; - serde_json::from_str::>(&input).map_err(GraphQLRequestError::BodyJSONError) + serde_json::from_str::>(&input) + .map_err(GraphQLRequestError::BodyJSONError) } pub async fn graphiql(graphql_endpoint: &str) -> Result, hyper::Error> { @@ -142,7 +143,7 @@ fn render_error(err: GraphQLRequestError) -> Response { async fn execute_request( root_node: Arc>, context: Arc, - request: GraphQLRequest, + request: GraphQLBatchRequest, ) -> Response where S: ScalarValue + Send + Sync + 'static, @@ -154,8 +155,9 @@ where MutationT::TypeInfo: Send + Sync, SubscriptionT::TypeInfo: Send + Sync, { - let (is_ok, body) = request.execute_sync(root_node, context); - let code = if is_ok { + let res = request.execute_sync(&*root_node, &context); + let body = Body::from(serde_json::to_string_pretty(&res).unwrap()); + let code = if res.is_ok() { StatusCode::OK } else { StatusCode::BAD_REQUEST @@ -172,20 +174,21 @@ where async fn execute_request_async( root_node: Arc>, context: Arc, - request: GraphQLRequest, + request: GraphQLBatchRequest, ) -> Response where S: ScalarValue + Send + Sync + 'static, CtxT: Send + Sync + 'static, QueryT: GraphQLTypeAsync + Send + Sync + 'static, MutationT: GraphQLTypeAsync + Send + Sync + 'static, - SubscriptionT: GraphQLTypeAsync + Send + Sync + 'static, + SubscriptionT: GraphQLSubscriptionType + Send + Sync, QueryT::TypeInfo: Send + Sync, MutationT::TypeInfo: Send + Sync, SubscriptionT::TypeInfo: Send + Sync, { - let (is_ok, body) = request.execute(root_node, context).await; - let code = if is_ok { + let res = request.execute(&*root_node, &context).await; + let body = Body::from(serde_json::to_string_pretty(&res).unwrap()); + let code = if res.is_ok() { StatusCode::OK } else { StatusCode::BAD_REQUEST @@ -263,100 +266,6 @@ fn new_html_response(code: StatusCode) -> Response { resp } -#[derive(serde_derive::Deserialize)] -#[serde(untagged)] -#[serde(bound = "InputValue: Deserialize<'de>")] -enum GraphQLRequest -where - S: ScalarValue, -{ - Single(JuniperGraphQLRequest), - Batch(Vec>), -} - -impl GraphQLRequest -where - S: ScalarValue, -{ - fn execute_sync<'a, CtxT: 'a, QueryT, MutationT, SubscriptionT>( - self, - root_node: Arc>, - context: Arc, - ) -> (bool, hyper::Body) - where - S: 'a + Send + Sync, - QueryT: GraphQLType + 'a, - MutationT: GraphQLType + 'a, - SubscriptionT: GraphQLType + 'a, - { - match self { - GraphQLRequest::Single(request) => { - let res = request.execute_sync(&root_node, &context); - let is_ok = res.is_ok(); - let body = Body::from(serde_json::to_string_pretty(&res).unwrap()); - (is_ok, body) - } - GraphQLRequest::Batch(requests) => { - let results: Vec<_> = requests - .into_iter() - .map(move |request| { - let root_node = root_node.clone(); - let res = request.execute_sync(&root_node, &context); - let is_ok = res.is_ok(); - let body = serde_json::to_string_pretty(&res).unwrap(); - (is_ok, body) - }) - .collect(); - - let is_ok = !results.iter().any(|&(is_ok, _)| !is_ok); - let bodies: Vec<_> = results.into_iter().map(|(_, body)| body).collect(); - let body = hyper::Body::from(format!("[{}]", bodies.join(","))); - (is_ok, body) - } - } - } - - async fn execute<'a, CtxT: 'a, QueryT, MutationT, SubscriptionT>( - self, - root_node: Arc>, - context: Arc, - ) -> (bool, hyper::Body) - where - S: Send + Sync, - QueryT: GraphQLTypeAsync + Send + Sync, - MutationT: GraphQLTypeAsync + Send + Sync, - SubscriptionT: GraphQLTypeAsync + Send + Sync, - QueryT::TypeInfo: Send + Sync, - MutationT::TypeInfo: Send + Sync, - SubscriptionT::TypeInfo: Send + Sync, - CtxT: Send + Sync, - { - match self { - GraphQLRequest::Single(request) => { - let res = request.execute(&*root_node, &context).await; - let is_ok = res.is_ok(); - let body = Body::from(serde_json::to_string_pretty(&res).unwrap()); - (is_ok, body) - } - GraphQLRequest::Batch(requests) => { - let futures = requests - .iter() - .map(|request| request.execute(&*root_node, &context)) - .collect::>(); - let results = futures::future::join_all(futures).await; - - let is_ok = results.iter().all(|res| res.is_ok()); - let bodies: Vec<_> = results - .into_iter() - .map(|res| serde_json::to_string_pretty(&res).unwrap()) - .collect(); - let body = hyper::Body::from(format!("[{}]", bodies.join(","))); - (is_ok, body) - } - } - } -} - #[derive(Debug)] enum GraphQLRequestError { BodyHyper(hyper::Error),