From db5eae6adc5b6499516d18d6741a4c293d09ecd3 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sat, 11 May 2019 14:22:28 +0200 Subject: [PATCH 1/5] Expose the operation name from `GraphQLRequest` Measuring the runtime of queries will only tell if there are slow queries. To find out which queries are slow you need the operation name. Getting the operation name was previously not possible from a Rocket request handler. This fixes that. --- juniper/src/http/mod.rs | 2 +- juniper_rocket/CHANGELOG.md | 2 +- juniper_rocket/src/lib.rs | 20 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/juniper/src/http/mod.rs b/juniper/src/http/mod.rs index 58e105d37..1ad139d58 100644 --- a/juniper/src/http/mod.rs +++ b/juniper/src/http/mod.rs @@ -36,7 +36,7 @@ where S: ScalarValue, { /// Returns the `operation_name` associated with this request. - fn operation_name(&self) -> Option<&str> { + pub fn operation_name(&self) -> Option<&str> { self.operation_name.as_ref().map(|oper_name| &**oper_name) } diff --git a/juniper_rocket/CHANGELOG.md b/juniper_rocket/CHANGELOG.md index ae8b5ebbf..d25645e8c 100644 --- a/juniper_rocket/CHANGELOG.md +++ b/juniper_rocket/CHANGELOG.md @@ -1,6 +1,6 @@ # master -- No changes yet +- Expose the operation name from `GraphQLRequest`. # [0.2.0] 2018-12-17 diff --git a/juniper_rocket/src/lib.rs b/juniper_rocket/src/lib.rs index 8f7461550..5ac179aa0 100644 --- a/juniper_rocket/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -107,6 +107,21 @@ where ), } } + + pub fn operation_name(&self) -> Option<&str> { + match self { + GraphQLBatchRequest::Single(req) => { + req.operation_name() + }, + GraphQLBatchRequest::Batch(reqs) => { + if reqs.len() == 1 { + reqs.get(0).and_then(|req| req.operation_name()) + } else { + None + } + }, + } + } } impl<'a, S> GraphQLBatchResponse<'a, S> @@ -173,6 +188,11 @@ where GraphQLResponse(status, json) } + + /// Returns the `operation_name` associated with this request. + pub fn operation_name(&self) -> Option<&str> { + self.0.operation_name() + } } impl GraphQLResponse { From 3b72d870dc829f12db84c869a090d601b9c560c0 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sat, 11 May 2019 20:31:48 +0200 Subject: [PATCH 2/5] Run `cargo fmt` --- juniper_rocket/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/juniper_rocket/src/lib.rs b/juniper_rocket/src/lib.rs index 5ac179aa0..08b96432c 100644 --- a/juniper_rocket/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -110,16 +110,14 @@ where pub fn operation_name(&self) -> Option<&str> { match self { - GraphQLBatchRequest::Single(req) => { - req.operation_name() - }, + GraphQLBatchRequest::Single(req) => req.operation_name(), GraphQLBatchRequest::Batch(reqs) => { if reqs.len() == 1 { reqs.get(0).and_then(|req| req.operation_name()) } else { None } - }, + } } } } From 34ae9422803f14e9a4fbb4be38a23a4f52f63736 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sat, 11 May 2019 20:35:27 +0200 Subject: [PATCH 3/5] Update changelog --- juniper/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md index 72fbc72ca..d4e0a25ef 100644 --- a/juniper/CHANGELOG.md +++ b/juniper/CHANGELOG.md @@ -12,6 +12,7 @@ The DirectiveLocation::InlineFragment had an invalid literal value, which broke third party tools like apollo cli. - The return type of `value::object::Object::iter/iter_mut` has changed to `impl Iter` [#312](https://github.com/graphql-rust/juniper/pull/312) +- Add `GraphQLRequest::operation_name` [#353](https://github.com/graphql-rust/juniper/pull/353) # [0.11.1] 2018-12-19 From 168a763253476d4cc72ac20a8d2b03dab89dfd94 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Sun, 12 May 2019 11:34:27 +0200 Subject: [PATCH 4/5] Return all operation names for batch requests --- juniper_rocket/CHANGELOG.md | 2 +- juniper_rocket/src/lib.rs | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/juniper_rocket/CHANGELOG.md b/juniper_rocket/CHANGELOG.md index e49755b02..d2c2e44b5 100644 --- a/juniper_rocket/CHANGELOG.md +++ b/juniper_rocket/CHANGELOG.md @@ -1,6 +1,6 @@ # master -- Expose the operation name from `GraphQLRequest`. +- Expose the operation names from `GraphQLRequest`. - Compatibility with the latest `juniper`. # [0.2.0] 2018-12-17 diff --git a/juniper_rocket/src/lib.rs b/juniper_rocket/src/lib.rs index 08b96432c..0739c97e4 100644 --- a/juniper_rocket/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -108,15 +108,11 @@ where } } - pub fn operation_name(&self) -> Option<&str> { + pub fn operation_names(&self) -> Vec> { match self { - GraphQLBatchRequest::Single(req) => req.operation_name(), + GraphQLBatchRequest::Single(req) => vec![req.operation_name()], GraphQLBatchRequest::Batch(reqs) => { - if reqs.len() == 1 { - reqs.get(0).and_then(|req| req.operation_name()) - } else { - None - } + reqs.iter().map(|req| req.operation_name()).collect() } } } @@ -187,9 +183,11 @@ where GraphQLResponse(status, json) } - /// Returns the `operation_name` associated with this request. - pub fn operation_name(&self) -> Option<&str> { - self.0.operation_name() + /// Returns the operation names associated with this request. + /// + /// For batch requests there will be multiple names. + pub fn operation_names(&self) -> Vec> { + self.0.operation_names() } } From 84c410dae5e8af5872ea33fcdb2b24a247563a29 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 15 May 2019 14:19:39 +0200 Subject: [PATCH 5/5] Add integration test for getting operation names in Rocket --- juniper_rocket/src/lib.rs | 40 ++++++++++++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/juniper_rocket/src/lib.rs b/juniper_rocket/src/lib.rs index 0739c97e4..f55de5e40 100644 --- a/juniper_rocket/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -534,14 +534,40 @@ mod tests { http_tests::run_http_test_suite(&integration); } + #[test] + fn test_operation_names() { + #[post("/", data = "")] + fn post_graphql_assert_operation_name_handler( + context: State, + request: super::GraphQLRequest, + schema: State, + ) -> super::GraphQLResponse { + assert_eq!(request.operation_names(), vec![Some("TestQuery")]); + request.execute(&schema, &context) + } + + let rocket = make_rocket_without_routes() + .mount("/", routes![post_graphql_assert_operation_name_handler]); + let client = Client::new(rocket).expect("valid rocket"); + + let req = client + .post("/") + .header(ContentType::JSON) + .body(r#"{"query": "query TestQuery {hero{name}}", "operationName": "TestQuery"}"#); + let resp = make_test_response(&req); + + assert_eq!(resp.status_code, 200); + } + fn make_rocket() -> Rocket { - rocket::ignite() - .manage(Database::new()) - .manage(Schema::new( - Database::new(), - EmptyMutation::::new(), - )) - .mount("/", routes![post_graphql_handler, get_graphql_handler]) + make_rocket_without_routes().mount("/", routes![post_graphql_handler, get_graphql_handler]) + } + + fn make_rocket_without_routes() -> Rocket { + rocket::ignite().manage(Database::new()).manage(Schema::new( + Database::new(), + EmptyMutation::::new(), + )) } fn make_test_response(request: &LocalRequest) -> http_tests::TestResponse {