From d37c97a38e7f375c6d2e9fff6e9053ac0ac905df Mon Sep 17 00:00:00 2001 From: vkill Date: Sat, 16 May 2020 10:34:06 +0800 Subject: [PATCH] async-graphql-tide: support make query_builder from get request --- async-graphql-tide/src/lib.rs | 24 ++++++++++++---- async-graphql-tide/tests/graphql.rs | 43 ++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 13 deletions(-) diff --git a/async-graphql-tide/src/lib.rs b/async-graphql-tide/src/lib.rs index edbdadab..ce631510 100644 --- a/async-graphql-tide/src/lib.rs +++ b/async-graphql-tide/src/lib.rs @@ -4,13 +4,16 @@ #![allow(clippy::type_complexity)] #![allow(clippy::needless_doctest_main)] -use async_graphql::http::GQLResponse; +use async_graphql::http::{GQLRequest, GQLResponse}; use async_graphql::{ IntoQueryBuilder, IntoQueryBuilderOpts, ObjectType, ParseRequestError, QueryBuilder, QueryResponse, Schema, SubscriptionType, }; use async_trait::async_trait; -use tide::{http::headers, Request, Response, Status, StatusCode}; +use tide::{ + http::{headers, Method}, + Request, Response, Status, StatusCode, +}; /// GraphQL request handler /// @@ -109,10 +112,19 @@ impl RequestExt for Request { self, opts: IntoQueryBuilderOpts, ) -> Result { - let content_type = self - .header(&headers::CONTENT_TYPE) - .and_then(|values| values.first().map(|value| value.to_string())); - (content_type, self).into_query_builder_opts(&opts).await + if self.method() == Method::Get { + match self.query::() { + Ok(gql_request) => gql_request.into_query_builder_opts(&opts).await, + Err(_) => Err(ParseRequestError::Io(std::io::Error::from( + std::io::ErrorKind::InvalidInput, + ))), + } + } else { + let content_type = self + .header(&headers::CONTENT_TYPE) + .and_then(|values| values.first().map(|value| value.to_string())); + (content_type, self).into_query_builder_opts(&opts).await + } } } diff --git a/async-graphql-tide/tests/graphql.rs b/async-graphql-tide/tests/graphql.rs index d420cbfc..004b2b8f 100644 --- a/async-graphql-tide/tests/graphql.rs +++ b/async-graphql-tide/tests/graphql.rs @@ -3,10 +3,8 @@ use serde_json::json; use smol::{Task, Timer}; use std::io::Read; use std::time::Duration; -use tide::Request; use async_graphql::*; -use async_graphql_tide::graphql; type Result = std::result::Result>; @@ -16,6 +14,9 @@ fn quickstart() -> Result<()> { let listen_addr = test_utils::find_listen_addr().await; let server = Task::>::spawn(async move { + use async_graphql_tide::{RequestExt, ResponseExt}; + use tide::{http::StatusCode, Request, Response, Status}; + struct QueryRoot; #[Object] impl QueryRoot { @@ -25,11 +26,16 @@ fn quickstart() -> Result<()> { } } - let mut app = tide::new(); - app.at("/").post(|req: Request<()>| async move { + async fn graphql(req: Request<()>) -> tide::Result { let schema = Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish(); - graphql(req, schema, |query_builder| query_builder).await - }); + let query_builder = req.body_graphql().await.status(StatusCode::BadRequest)?; + Ok(Response::new(StatusCode::Ok) + .body_graphql(query_builder.execute(&schema).await) + .status(StatusCode::InternalServerError)?) + } + + let mut app = tide::new(); + app.at("/").post(graphql).get(graphql); app.listen(&listen_addr).await?; Ok(()) @@ -38,6 +44,7 @@ fn quickstart() -> Result<()> { let client = Task::>::spawn(async move { Timer::after(Duration::from_millis(300)).await; + // let resp = reqwest::Client::new() .post(format!("http://{}", listen_addr).as_str()) .body(r#"{"query":"{ add(a: 10, b: 20) }"}"#) @@ -47,7 +54,25 @@ fn quickstart() -> Result<()> { assert_eq!(resp.status(), reqwest::StatusCode::OK); let string = resp.text().await?; - println!("{}", string); + println!("via post {}", string); + + assert_eq!(string, json!({"data": {"add": 30}}).to_string()); + + // + let resp = reqwest::Client::new() + .get( + format!( + "http://{}?query=%7B%20add%28a%3A%2010%2C%20b%3A%2020%29%20%7D", + listen_addr + ) + .as_str(), + ) + .send() + .await?; + + assert_eq!(resp.status(), reqwest::StatusCode::OK); + let string = resp.text().await?; + println!("via get {}", string); assert_eq!(string, json!({"data": {"add": 30}}).to_string()); @@ -67,6 +92,8 @@ fn hello() -> Result<()> { let listen_addr = test_utils::find_listen_addr().await; let server = Task::>::spawn(async move { + use tide::Request; + struct Hello(String); struct QueryRoot; #[Object] @@ -154,6 +181,8 @@ fn upload() -> Result<()> { let listen_addr = test_utils::find_listen_addr().await; let server = Task::>::spawn(async move { + use tide::Request; + struct QueryRoot; #[Object] impl QueryRoot {}