juniper/juniper_axum/examples/custom.rs

89 lines
2.9 KiB
Rust

//! This example demonstrates custom [`Handler`]s with [`axum`], using the [`starwars::schema`].
//!
//! [`Handler`]: axum::handler::Handler
//! [`starwars::schema`]: juniper::tests::fixtures::starwars::schema
use std::{net::SocketAddr, sync::Arc};
use axum::{
extract::WebSocketUpgrade,
response::{Html, Response},
routing::{get, on, MethodFilter},
Extension, Router,
};
use juniper::{
tests::fixtures::starwars::schema::{Database, Query, Subscription},
EmptyMutation, RootNode,
};
use juniper_axum::{
extract::JuniperRequest, graphiql, playground, response::JuniperResponse, subscriptions,
};
use juniper_graphql_ws::ConnectionConfig;
use tokio::net::TcpListener;
type Schema = RootNode<'static, Query, EmptyMutation<Database>, Subscription>;
async fn homepage() -> Html<&'static str> {
"<html><h1>juniper_axum/custom example</h1>\
<div>visit <a href=\"/graphiql\">GraphiQL</a></div>\
<div>visit <a href=\"/playground\">GraphQL Playground</a></div>\
</html>"
.into()
}
pub async fn custom_subscriptions(
Extension(schema): Extension<Arc<Schema>>,
Extension(database): Extension<Database>,
ws: WebSocketUpgrade,
) -> Response {
ws.protocols(["graphql-transport-ws", "graphql-ws"])
.max_frame_size(1024)
.max_message_size(1024)
.max_write_buffer_size(100)
.on_upgrade(move |socket| {
subscriptions::serve_ws(
socket,
schema,
ConnectionConfig::new(database).with_max_in_flight_operations(10),
)
})
}
async fn custom_graphql(
Extension(schema): Extension<Arc<Schema>>,
Extension(database): Extension<Database>,
JuniperRequest(request): JuniperRequest,
) -> JuniperResponse {
JuniperResponse(request.execute(&*schema, &database).await)
}
#[tokio::main]
async fn main() {
tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
.init();
let schema = Schema::new(Query, EmptyMutation::new(), Subscription);
let database = Database::new();
let app = Router::new()
.route(
"/graphql",
on(MethodFilter::GET.or(MethodFilter::POST), custom_graphql),
)
.route("/subscriptions", get(custom_subscriptions))
.route("/graphiql", get(graphiql("/graphql", "/subscriptions")))
.route("/playground", get(playground("/graphql", "/subscriptions")))
.route("/", get(homepage))
.layer(Extension(Arc::new(schema)))
.layer(Extension(database));
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
let listener = TcpListener::bind(addr)
.await
.unwrap_or_else(|e| panic!("failed to listen on {addr}: {e}"));
tracing::info!("listening on {addr}");
axum::serve(listener, app)
.await
.unwrap_or_else(|e| panic!("failed to run `axum::serve`: {e}"));
}