Skip to main content

mina_node_native/http_server/routes/
graphql.rs

1//! GraphQL endpoints.
2//!
3//! - `POST /graphql` - Execute GraphQL queries and mutations
4//! - `GET /graphiql` - GraphiQL IDE (requires `graphiql` feature, on by default)
5//!
6//! Note: `/playground` is intentionally not included. GraphQL Playground was
7//! deprecated and merged into GraphiQL 2.0, making them redundant.
8
9use std::sync::Arc;
10
11use axum::{
12    extract::State,
13    response::{Html, IntoResponse},
14    routing::{get, post},
15    Extension, Json, Router,
16};
17use juniper::{http::GraphQLBatchRequest, EmptySubscription, RootNode};
18
19use crate::{
20    graphql::{Context, Mutation, Query},
21    http_server::AppState,
22};
23
24type Schema = RootNode<Query, Mutation, EmptySubscription<Context>>;
25
26/// Registers GraphQL routes on the router.
27pub fn routes(router: Router<AppState>) -> Router<AppState> {
28    let schema = Arc::new(Schema::new(Query, Mutation, EmptySubscription::new()));
29
30    let router = router.route("/graphql", post(graphql_handler));
31
32    #[cfg(feature = "graphiql")]
33    let router = router.route("/graphiql", get(graphiql_handler));
34
35    router.layer(Extension(schema))
36}
37
38/// Handles GraphQL POST requests.
39async fn graphql_handler(
40    State(state): State<AppState>,
41    Extension(schema): Extension<Arc<Schema>>,
42    Json(request): Json<GraphQLBatchRequest>,
43) -> impl IntoResponse {
44    let context = Context::new(state.rpc_sender().clone());
45    let response = request.execute(&*schema, &context).await;
46    Json(response)
47}
48
49/// Serves the GraphiQL IDE.
50#[cfg(feature = "graphiql")]
51async fn graphiql_handler() -> impl IntoResponse {
52    Html(juniper::http::graphiql::graphiql_source("/graphql", None))
53}