From 2518eff0c99448475a49a00ffc71e35b3615f978 Mon Sep 17 00:00:00 2001 From: David Pedersen Date: Wed, 15 May 2019 16:26:40 +0200 Subject: [PATCH] Expose the operation name from `juniper_rocket::GraphQLRequest` (#353) 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/CHANGELOG.md | 5 ++-- juniper/src/http/mod.rs | 2 +- juniper_rocket/CHANGELOG.md | 1 + juniper_rocket/src/lib.rs | 56 ++++++++++++++++++++++++++++++++----- 4 files changed, 54 insertions(+), 10 deletions(-) diff --git a/juniper/CHANGELOG.md b/juniper/CHANGELOG.md index d3e3660a..f88db045 100644 --- a/juniper/CHANGELOG.md +++ b/juniper/CHANGELOG.md @@ -25,10 +25,11 @@ This should not have any impact on your code, since juniper already was 2018 com - Fix introspection query validity The DirectiveLocation::InlineFragment had an invalid literal value, which broke third party tools like apollo cli. -- Added GraphQL Playground integration - The DirectiveLocation::InlineFragment had an invalid literal value, +- Added GraphQL Playground integration. + 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 diff --git a/juniper/src/http/mod.rs b/juniper/src/http/mod.rs index 58e105d3..1ad139d5 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 a2890b19..d2c2e44b 100644 --- a/juniper_rocket/CHANGELOG.md +++ b/juniper_rocket/CHANGELOG.md @@ -1,5 +1,6 @@ # master +- 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 f4c9f999..9fcc5034 100644 --- a/juniper_rocket/src/lib.rs +++ b/juniper_rocket/src/lib.rs @@ -108,6 +108,15 @@ where ), } } + + pub fn operation_names(&self) -> Vec> { + match self { + GraphQLBatchRequest::Single(req) => vec![req.operation_name()], + GraphQLBatchRequest::Batch(reqs) => { + reqs.iter().map(|req| req.operation_name()).collect() + } + } + } } impl<'a, S> GraphQLBatchResponse<'a, S> @@ -174,6 +183,13 @@ where GraphQLResponse(status, json) } + + /// 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() + } } impl GraphQLResponse { @@ -519,14 +535,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 {