GraphQL Client Typed Queries Rust
Execute GraphQL queries from Rust with graphql-client, deriving response types from the query document and variables.
Code
use graphql_client::{GraphQLQuery, Response};
// queries/top_customers.graphql:
// query TopCustomers($region: Region!, $first: Int!) {
// customers(region: $region, first: $first) {
// edges { node { id name lifetimeValue } }
// }
// }
#[derive(GraphQLQuery)]
#[graphql(
query_path = "queries/top_customers.graphql",
schema_path = "schemas/customer.graphql",
response_derives = "Debug"
)]
pub struct TopCustomers;
type Customer = top_customers::TopCustomersCustomersEdgesNode;
async fn fetch_top_customers(
region: &str,
first: i64,
) -> Result<Vec<Customer>, Box<dyn std::error::Error>> {
let variables = top_customers::Variables {
region: region.into(),
first,
};
let request_body = TopCustomers::build_query(variables);
let client = reqwest::Client::new();
let res = client
.post("https://api.example.com/graphql")
.json(&request_body)
.send()
.await?
.error_for_status()?;
let response_body: Response<top_customers::ResponseData> = res.json().await?;
let data = response_body
.data
.ok_or("query returned no data")?;
if let Some(errors) = response_body.errors {
for err in &errors {
eprintln!("graphql error: {:?}", err.message);
}
}
let customers: Vec<Customer> = data
.customers
.map(|conn| {
conn.edges
.into_iter()
.filter_map(|edge| edge.map(|e| e.node))
.collect()
})
.unwrap_or_default();
Ok(customers)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let customers = fetch_top_customers("eu", 5).await?;
for customer in customers {
println!("{:?} value={}", customer, customer.lifetime_value);
}
Ok(())
}Report a problem with this exampleOpens a pre-filled issue on GitHub.