pub mod extract; pub mod response; use std::{future, net::SocketAddr}; use axum::{ extract::{ConnectInfo, Extension, State}, response::{Html, IntoResponse}, }; use juniper_graphql_ws::Schema; use self::{extract::JuniperRequest, response::JuniperResponse}; pub trait FromStateAndClientAddr { fn build(state: S, client_addr: SocketAddr) -> C; } #[cfg_attr(text, axum::debug_handler)] pub async fn graphql( ConnectInfo(addr): ConnectInfo, State(state): State, Extension(schema): Extension, JuniperRequest(req): JuniperRequest, ) -> impl IntoResponse where S: Schema, // TODO: Refactor in the way we don't depend on `juniper_graphql_ws::Schema` here. S::Context: FromStateAndClientAddr, C: Clone, { let context = S::Context::build(state.clone(), addr); JuniperResponse(req.execute(schema.root_node(), &context).await).into_response() } /// Creates a [`Handler`] that replies with an HTML page containing [GraphiQL]. /// /// This does not handle routing, so you can mount it on any endpoint. /// /// # Example /// /// ```rust /// use axum::{routing::get, Router}; /// use juniper_axum::graphiql; /// /// let app: Router = Router::new() /// .route("/", get(graphiql("/graphql", "/subscriptions"))); /// ``` /// /// [`Handler`]: axum::handler::Handler /// [GraphiQL]: https://github.com/graphql/graphiql pub fn graphiql<'a>( graphql_endpoint_url: &str, subscriptions_endpoint_url: impl Into>, ) -> impl FnOnce() -> future::Ready> + Clone + Send { let html = Html(juniper::http::graphiql::graphiql_source( graphql_endpoint_url, subscriptions_endpoint_url.into(), )); || future::ready(html) } /// Creates a [`Handler`] that replies with an HTML page containing [GraphQL Playground]. /// /// This does not handle routing, so you can mount it on any endpoint. /// /// # Example /// /// ```rust /// use axum::{routing::get, Router}; /// use juniper_axum::playground; /// /// let app: Router = Router::new() /// .route("/", get(playground("/graphql", "/subscriptions"))); /// ``` /// /// [`Handler`]: axum::handler::Handler /// [GraphQL Playground]: https://github.com/prisma/graphql-playground pub fn playground<'a>( graphql_endpoint_url: &str, subscriptions_endpoint_url: impl Into>, ) -> impl FnOnce() -> future::Ready> + Clone + Send { let html = Html(juniper::http::playground::playground_source( graphql_endpoint_url, subscriptions_endpoint_url.into(), )); || future::ready(html) }