iota_graphql_rpc/server/
graphiql_server.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use axum::extract::Path;
6use tokio_util::sync::CancellationToken;
7use tracing::info;
8
9use crate::{
10    config::{ServerConfig, Version},
11    error::Error,
12    server::builder::ServerBuilder,
13};
14
15async fn graphiql(
16    ide_title: axum::Extension<Option<String>>,
17    path: Option<Path<String>>,
18) -> impl axum::response::IntoResponse {
19    let endpoint = if let Some(Path(path)) = path {
20        format!("/graphql/{path}")
21    } else {
22        "/graphql".to_string()
23    };
24    let gq = async_graphql::http::GraphiQLSource::build()
25        .endpoint(&endpoint)
26        .subscription_endpoint("/subscriptions");
27    if let axum::Extension(Some(title)) = ide_title {
28        axum::response::Html(gq.title(&title).finish())
29    } else {
30        axum::response::Html(gq.finish())
31    }
32}
33
34pub async fn start_graphiql_server(
35    server_config: &ServerConfig,
36    version: &Version,
37    cancellation_token: CancellationToken,
38) -> Result<(), Error> {
39    info!("Starting server with config: {:#?}", server_config);
40    info!("Server version: {}", version);
41    start_graphiql_server_impl(
42        ServerBuilder::from_config(server_config, version, cancellation_token).await?,
43        server_config.ide.ide_title.clone(),
44    )
45    .await
46}
47
48async fn start_graphiql_server_impl(
49    server_builder: ServerBuilder,
50    ide_title: String,
51) -> Result<(), Error> {
52    let address = server_builder.address();
53
54    // Add GraphiQL IDE handler on GET request to `/`` endpoint
55    let server = server_builder
56        .route("/", axum::routing::get(graphiql))
57        .route("/{version}", axum::routing::get(graphiql))
58        .route("/graphql", axum::routing::get(graphiql))
59        .route("/graphql/{version}", axum::routing::get(graphiql))
60        .layer(axum::extract::Extension(Some(ide_title)))
61        .build()?;
62
63    info!("Launch GraphiQL IDE at: http://{}", address);
64
65    server.run().await
66}