#![feature(async_await, futures_api)]
use http::status::StatusCode;
use juniper::graphql_object;
use std::sync::{atomic, Arc};
use tide::{body, App, AppData, IntoResponse, Response};
#[derive(Clone, Default)]
struct Context(Arc<atomic::AtomicIsize>);
impl juniper::Context for Context {}
struct Query;
graphql_object!(Query: Context |&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: Context |&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(
ctx: AppData<Context>,
query: body::Json<juniper::http::GraphQLRequest>,
) -> Response {
let response = query.execute(&Schema::new(Query, Mutation), &ctx);
let status = if response.is_ok() {
StatusCode::OK
} else {
StatusCode::BAD_REQUEST
};
body::Json(response).with_status(status).into_response()
}
fn main() {
let mut app = App::new(Context::default());
app.at("/graphql").post(handle_graphql);
app.serve();
}