Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions graphql_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ pub trait GraphQLQuery {

/// Produce a GraphQL query struct that can be JSON serialized and sent to a GraphQL API.
fn build_query(variables: Self::Variables) -> QueryBody<Self::Variables>;
/// Produce a GraphQL batch query struct that can be JSON serialized and sent to a GraphQL API.
fn build_batch_query(variables: Vec<Self::Variables>) -> Vec<QueryBody<Self::Variables>>;
}

/// The form in which queries are sent over HTTP in most implementations. This will be built using the [`GraphQLQuery`] trait normally.
Expand Down
26 changes: 26 additions & 0 deletions graphql_client/src/reqwest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ pub async fn post_graphql<Q: GraphQLQuery, U: reqwest::IntoUrl>(
reqwest_response.json().await
}

/// Use the provided reqwest::Client to post a GraphQL request.
#[cfg(any(feature = "reqwest", feature = "reqwest-rustls"))]
pub async fn post_graphql_batch<Q: GraphQLQuery, U: reqwest::IntoUrl>(
client: &reqwest::Client,
url: U,
variables: Vec<Q::Variables>,
) -> Result<crate::Response<Q::ResponseData>, reqwest::Error> {
let body = Q::build_batch_query(variables);
let reqwest_response = client.post(url).json(&body).send().await?;

reqwest_response.json().await
}

/// Use the provided reqwest::Client to post a GraphQL request.
#[cfg(feature = "reqwest-blocking")]
pub fn post_graphql_blocking<Q: GraphQLQuery, U: reqwest::IntoUrl>(
Expand All @@ -28,3 +41,16 @@ pub fn post_graphql_blocking<Q: GraphQLQuery, U: reqwest::IntoUrl>(

reqwest_response.json()
}

/// Use the provided reqwest::Client to post a GraphQL request.
#[cfg(feature = "reqwest-blocking")]
pub fn post_graphql_blocking_batch<Q: GraphQLQuery, U: reqwest::IntoUrl>(
client: &reqwest::blocking::Client,
url: U,
variables: Vec<Q::Variables>,
) -> Result<crate::Response<Q::ResponseData>, reqwest::Error> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be Result<Vec<crate::Response<...>>, _>?

let body = Q::build_batch_query(variables);
let reqwest_response = client.post(url).json(&body).send()?;

reqwest_response.json()
}
28 changes: 28 additions & 0 deletions graphql_client/tests/batch_queries.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use graphql_client::*;

#[derive(GraphQLQuery)]
#[graphql(
query_path = "tests/operation_selection/queries.graphql",
schema_path = "tests/operation_selection/schema.graphql",
response_derives = "Debug, PartialEq, Eq"
)]
pub struct Echo;

#[test]
fn batch_query() {
let echo_variables = vec![
echo::Variables {
msg: Some("hi".to_string()),
},
echo::Variables {
msg: Some("hello".to_string()),
},
];
let echo_batch_queries: serde_json::Value =
serde_json::to_value(Echo::build_batch_query(echo_variables))
.expect("Failed to serialize the query!");
assert_eq!(
echo_batch_queries.to_string(),
r#"[{"operationName":"Echo","query":"query Heights($buildingId: ID!, $mountainName: String) {\n mountainHeight(name: $mountainName)\n buildingHeight(id: $buildingId)\n}\n\nquery Echo($msg: String) {\n echo(msg: $msg)\n}\n","variables":{"msg":"hi"}},{"operationName":"Echo","query":"query Heights($buildingId: ID!, $mountainName: String) {\n mountainHeight(name: $mountainName)\n buildingHeight(id: $buildingId)\n}\n\nquery Echo($msg: String) {\n echo(msg: $msg)\n}\n","variables":{"msg":"hello"}}]"#
);
}
Loading