use http::status::StatusCode;
use juniper::graphql_object;
use std::sync::{atomic, Arc};
use tide::{error::ResultExt, response, App, Context, EndpointResult};
#[derive(Clone, Default)]
struct Data(Arc<atomic::AtomicIsize>);
impl juniper::Context for Data {}
struct Query;
graphql_object!(Query: Data |&self| {
field accumulator(&executor) -> i32 as "Current value of the accumulator" {
executor.context().0.load(atomic::Ordering::Relaxed) as i32
}
});
struct Mutation;
graphql_object!(Mutation: Data |&self| {
field add(&executor, by: i32) -> i32 as "Add given value to the accumulator." {
executor.context().0.fetch_add(by as isize, atomic::Ordering::Relaxed) as i32 + by
}
});
type Schema = juniper::RootNode<'static, Query, Mutation>;
async fn handle_graphql(mut cx: Context<Data>) -> EndpointResult {
let query: juniper::http::GraphQLRequest = cx.body_json().await.client_err()?;
let schema = Schema::new(Query, Mutation);
let response = query.execute(&schema, cx.state());
let status = if response.is_ok() {
StatusCode::OK
} else {
StatusCode::BAD_REQUEST
};
let mut resp = response::json(response);
*resp.status_mut() = status;
Ok(resp)
}
fn main() {
let mut app = App::with_state(Data::default());
app.at("/graphql").post(handle_graphql);
app.serve("127.0.0.1:8000").unwrap();
}