diff --git a/examples/call.graphql b/examples/call.graphql index b97730ce57..8d49788d81 100644 --- a/examples/call.graphql +++ b/examples/call.graphql @@ -11,7 +11,7 @@ type Post { type Query { user(id: Int!): User @http(path: "/users/{{args.id}}") - firstUser: User @call(query: "user", args: {id: "1"}) + firstUser: User @call(query: "user", args: {id: 1}) postFromUser(userId: Int!): [Post] @http(path: "/posts?userId={{args.userId}}") } diff --git a/src/blueprint/operators/call.rs b/src/blueprint/operators/call.rs index a33cbedf66..d9506e4d5d 100644 --- a/src/blueprint/operators/call.rs +++ b/src/blueprint/operators/call.rs @@ -1,5 +1,7 @@ use std::collections::hash_map::Iter; +use serde_json::Value; + use crate::blueprint::*; use crate::config; use crate::config::{Field, GraphQLOperationType, KeyValues}; @@ -8,7 +10,7 @@ use crate::mustache::{Mustache, Segment}; use crate::try_fold::TryFold; use crate::valid::{Valid, Validator}; -fn find_value<'a>(args: &'a Iter<'a, String, String>, key: &'a String) -> Option<&'a String> { +fn find_value<'a>(args: &'a Iter<'a, String, Value>, key: &'a String) -> Option<&'a Value> { args.clone() .find_map(|(k, value)| if k == key { Some(value) } else { None }) } @@ -94,7 +96,7 @@ pub fn compile_call( } fn replace_key_values<'a>( - args: &'a Iter<'a, String, String>, + args: &'a Iter<'a, String, Value>, ) -> impl Fn(KeyValues) -> KeyValues + 'a { |key_values| { KeyValues( @@ -106,7 +108,7 @@ fn replace_key_values<'a>( } } -fn replace_string<'a>(args: &'a Iter<'a, String, String>) -> impl Fn(String) -> String + 'a { +fn replace_string<'a>(args: &'a Iter<'a, String, Value>) -> impl Fn(String) -> String + 'a { |str| { let mustache = Mustache::parse(&str).unwrap(); @@ -129,7 +131,7 @@ fn get_type_and_field(call: &config::Call) -> Option<(String, String)> { fn get_field_and_field_name<'a>( call: &'a config::Call, config_module: &'a ConfigModule, -) -> Valid<(&'a Field, String, Iter<'a, String, String>), String> { +) -> Valid<(&'a Field, String, Iter<'a, String, Value>), String> { Valid::from_option( get_type_and_field(call), "call must have query or mutation".to_string(), @@ -151,7 +153,7 @@ fn get_field_and_field_name<'a>( }) } -fn replace_mustache_value(value: &Mustache, args: &Iter<'_, String, String>) -> Mustache { +fn replace_mustache_value(value: &Mustache, args: &Iter<'_, String, Value>) -> Mustache { value .get_segments() .iter() @@ -160,7 +162,7 @@ fn replace_mustache_value(value: &Mustache, args: &Iter<'_, String, String>) -> Segment::Expression(expression) => { if expression[0] == "args" { let value = find_value(args, &expression[1]).unwrap(); - let item = Mustache::parse(value).unwrap(); + let item = Mustache::parse(value.to_string().as_str()).unwrap(); let expression = item.get_segments().first().unwrap().to_owned().to_owned(); diff --git a/src/config/config.rs b/src/config/config.rs index f4579cc7f6..3762810e2f 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -608,7 +608,7 @@ pub struct Call { pub mutation: Option, /// The arguments of the field on the `Query` type that you want to call. For instance `{id: "{{value.userId}}"}`. - pub args: HashMap, + pub args: HashMap, } #[derive(Serialize, Deserialize, Clone, Debug, Default, PartialEq, Eq, schemars::JsonSchema)] diff --git a/tests/execution/call-mutation.md b/tests/execution/call-mutation.md index 0b3ba8fa03..adc22a41b4 100644 --- a/tests/execution/call-mutation.md +++ b/tests/execution/call-mutation.md @@ -24,10 +24,12 @@ type Mutation { attachPostToUser(userId: Int!, postId: Int!): User @http(body: "{\"postId\":{{args.postId}}}", method: "PATCH", path: "/users/{{args.userId}}") attachPostToFirstUser(postId: Int!): User - @call(mutation: "attachPostToUser", args: {postId: "{{args.postId}}", userId: "1"}) + @call(mutation: "attachPostToUser", args: {postId: "{{args.postId}}", userId: 1}) insertPost(input: PostInput): Post @http(body: "{{args.input}}", method: "POST", path: "/posts") + insertMockedPost: Post + @call(mutation: "insertPost", args: {input: {body: "post-body", title: "post-title", userId: 1}}) insertPostToFirstUser(input: PostInputWithoutUserId): Post - @call(mutation: "insertPostToUser", args: {input: "{{args.input}}", userId: "1"}) + @call(mutation: "insertPostToUser", args: {input: "{{args.input}}", userId: 1}) insertPostToUser(input: PostInputWithoutUserId!, userId: Int!): Post @http(body: "{{args.input}}", method: "POST", path: "/users/{{args.userId}}/posts") } @@ -132,4 +134,8 @@ type User { url: http://localhost:8080/graphql body: query: 'mutation { insertPostToFirstUser(input: { body: "post-body", title: "post-title" }) { body } }' +- method: POST + url: http://localhost:8080/graphql + body: + query: "mutation { insertMockedPost { body } }" ``` diff --git a/tests/execution/call-operator.md b/tests/execution/call-operator.md index aa74ce0771..d28121ef07 100644 --- a/tests/execution/call-operator.md +++ b/tests/execution/call-operator.md @@ -106,7 +106,7 @@ type Post { userGraphQL: User @call(query: "userGraphQL", args: {id: "{{value.userId}}"}) userGraphQLHeaders: User @call(query: "userGraphQLHeaders", args: {id: "{{value.userId}}"}) news: NewsData! @call(query: "news", args: {}) - newsWithPortArg: NewsData! @call(query: "news", args: {port: "50051"}) + newsWithPortArg: NewsData! @call(query: "news", args: {port: 50051}) } ``` diff --git a/tests/snapshots/execution_spec__call-mutation.md_assert_4.snap b/tests/snapshots/execution_spec__call-mutation.md_assert_4.snap new file mode 100644 index 0000000000..7ca89a4e51 --- /dev/null +++ b/tests/snapshots/execution_spec__call-mutation.md_assert_4.snap @@ -0,0 +1,17 @@ +--- +source: tests/execution_spec.rs +expression: response +--- +{ + "status": 200, + "headers": { + "content-type": "application/json" + }, + "body": { + "data": { + "insertMockedPost": { + "body": "post-body" + } + } + } +} diff --git a/tests/snapshots/execution_spec__call-mutation.md_client.snap b/tests/snapshots/execution_spec__call-mutation.md_client.snap index 2e85113bd6..1e39f82dd5 100644 --- a/tests/snapshots/execution_spec__call-mutation.md_client.snap +++ b/tests/snapshots/execution_spec__call-mutation.md_client.snap @@ -5,6 +5,7 @@ expression: client type Mutation { attachPostToFirstUser(postId: Int!): User attachPostToUser(postId: Int!, userId: Int!): User + insertMockedPost: Post insertPost(input: PostInput): Post insertPostToFirstUser(input: PostInputWithoutUserId): Post insertPostToUser(input: PostInputWithoutUserId!, userId: Int!): Post diff --git a/tests/snapshots/execution_spec__call-mutation.md_merged.snap b/tests/snapshots/execution_spec__call-mutation.md_merged.snap index c7d45da7b2..f3d0039c7c 100644 --- a/tests/snapshots/execution_spec__call-mutation.md_merged.snap +++ b/tests/snapshots/execution_spec__call-mutation.md_merged.snap @@ -20,10 +20,11 @@ input PostInputWithoutUserId { } type Mutation { - attachPostToFirstUser(postId: Int!): User @call(mutation: "attachPostToUser", args: {postId: "{{args.postId}}", userId: "1"}) + attachPostToFirstUser(postId: Int!): User @call(mutation: "attachPostToUser", args: {postId: "{{args.postId}}", userId: 1}) attachPostToUser(postId: Int!, userId: Int!): User @http(body: "{\"postId\":{{args.postId}}}", method: "PATCH", path: "/users/{{args.userId}}") + insertMockedPost: Post @call(mutation: "insertPost", args: {input: {body: "post-body", title: "post-title", userId: 1}}) insertPost(input: PostInput): Post @http(body: "{{args.input}}", method: "POST", path: "/posts") - insertPostToFirstUser(input: PostInputWithoutUserId): Post @call(mutation: "insertPostToUser", args: {input: "{{args.input}}", userId: "1"}) + insertPostToFirstUser(input: PostInputWithoutUserId): Post @call(mutation: "insertPostToUser", args: {input: "{{args.input}}", userId: 1}) insertPostToUser(input: PostInputWithoutUserId!, userId: Int!): Post @http(body: "{{args.input}}", method: "POST", path: "/users/{{args.userId}}/posts") } diff --git a/tests/snapshots/execution_spec__call-operator.md_merged.snap b/tests/snapshots/execution_spec__call-operator.md_merged.snap index c09e5ac7bd..5c064fb12c 100644 --- a/tests/snapshots/execution_spec__call-operator.md_merged.snap +++ b/tests/snapshots/execution_spec__call-operator.md_merged.snap @@ -21,7 +21,7 @@ type Post { body: String id: Int news: NewsData! @call(query: "news", args: {}) - newsWithPortArg: NewsData! @call(query: "news", args: {port: "50051"}) + newsWithPortArg: NewsData! @call(query: "news", args: {port: 50051}) title: String user: User @call(query: "user", args: {id: "{{value.userId}}"}) user1: User @call(query: "user1", args: {})