1#[macro_use]
2extern crate tower_web;
3
4use http::StatusCode;
5use tokio::prelude::*;
6
7use juniper::GraphQLType;
8use juniper::RootNode;
9
10#[derive(Debug, Extract, Deserialize)]
11pub struct GraphQLRequest {
12 #[serde(flatten)]
13 gq: juniper::http::GraphQLRequest,
14}
15
16#[derive(Debug, Response, Serialize)]
17pub struct GraphQLResponse {
18 #[serde(flatten)]
19 inner: serde_json::Value,
20
21 #[web(header)]
22 status: u16,
23}
24
25pub fn graphiql_source(
26 graphql_endpoint_url: &str,
27) -> impl Future<Item = String, Error = ()> + Send {
28 future::ok(juniper::graphiql::graphiql_source(graphql_endpoint_url))
29}
30
31impl GraphQLRequest {
32 pub fn execute<CtxT, QueryT, MutationT>(
33 &self,
34 root_node: &RootNode<QueryT, MutationT>,
35 context: &CtxT,
36 ) -> impl Future<Item = GraphQLResponse, Error = ()>
37 where
38 QueryT: GraphQLType<Context = CtxT>,
39 MutationT: GraphQLType<Context = CtxT>,
40 {
41 let response = self.gq.execute(root_node, context);
42 let status = if response.is_ok() {
43 StatusCode::OK
44 } else {
45 StatusCode::BAD_REQUEST
46 };
47 let json = serde_json::to_value(&response).unwrap();
48 future::ok(GraphQLResponse {
49 inner: json,
50 status: status.into(),
51 })
52 }
53}