From 5de218bca912bc7bd1bb4d369de070160698d192 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 21 Sep 2023 10:41:05 +0100 Subject: [PATCH] initial empty openapi/swagger --- nym-node/Cargo.toml | 15 ++++++++++++--- nym-node/src/http/router/api/mod.rs | 3 +++ nym-node/src/http/router/api/v1/build_info.rs | 12 +++++++++++- nym-node/src/http/router/api/v1/mod.rs | 2 ++ nym-node/src/http/router/api/v1/openapi.rs | 19 +++++++++++++++++++ nym-node/src/http/router/mod.rs | 5 +++++ 6 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 nym-node/src/http/router/api/v1/openapi.rs diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index bd7f560828..e8eec0332c 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -12,15 +12,24 @@ license.workspace = true [dependencies] anyhow = { workspace = true } -axum = { workspace = true } bytes = "1.5.0" -hyper = { workspace = true } -mime = "0.3.17" serde = { workspace = true, features = ["derive"] } serde_yaml = "0.9.25" thiserror = { workspace = true } tracing = { workspace = true } + +# HTTP API: +axum = { workspace = true } +mime = "0.3.17" +hyper = { workspace = true } tower = { version = "0.4.13" } tower-http = { version = "0.4.4", features = ["fs"] } +utoipa = { version = "3.5.0", features = ["axum_extras"] } +utoipa-swagger-ui = { version = "3.1.5", features = ["axum"] } + +# if we ever wanted redoc/rapidoc bridges: +#utoipa-redoc = { version = "0.1.0", features = ["axum"] } +#utoipa-rapidoc = { version = "0.1.0", features = ["axum"] } + nym-bin-common = { path = "../common/bin-common" } diff --git a/nym-node/src/http/router/api/mod.rs b/nym-node/src/http/router/api/mod.rs index ce69ef9abb..8e06bd3e57 100644 --- a/nym-node/src/http/router/api/mod.rs +++ b/nym-node/src/http/router/api/mod.rs @@ -11,6 +11,7 @@ pub mod v1; pub(crate) mod routes { pub(crate) const V1: &str = "/v1"; + pub(crate) const SWAGGER: &str = "/swagger"; } #[derive(Debug, Clone, Default)] @@ -20,6 +21,8 @@ pub struct Config { pub(super) fn routes(config: Config) -> Router { Router::new().nest_service(routes::V1, v1::routes(config.v1_config)) + // .nest(routes::SWAGGER, openapi::route()) + // .nest(routes::SWAGGER, openapi::route()) } #[derive(Default, Debug, Serialize, Deserialize, Copy, Clone)] diff --git a/nym-node/src/http/router/api/v1/build_info.rs b/nym-node/src/http/router/api/v1/build_info.rs index 3c9126ca08..cd64992588 100644 --- a/nym-node/src/http/router/api/v1/build_info.rs +++ b/nym-node/src/http/router/api/v1/build_info.rs @@ -5,7 +5,17 @@ use crate::http::router::api::Output; use axum::extract::Query; use axum::response::IntoResponse; -pub async fn build_info(output: Query>) -> impl IntoResponse { +#[utoipa::path( + get, + path = "/", + responses( + (status=200, description ="", body = ()) + ), + params( + ("output" = Option, Query, description = "") + ) +)] +pub async fn build_info(Query(output): Query>) -> impl IntoResponse { let output = output.unwrap_or_default(); todo!() diff --git a/nym-node/src/http/router/api/v1/mod.rs b/nym-node/src/http/router/api/v1/mod.rs index bae5145045..07b8a1cfdc 100644 --- a/nym-node/src/http/router/api/v1/mod.rs +++ b/nym-node/src/http/router/api/v1/mod.rs @@ -11,6 +11,7 @@ pub mod build_info; pub mod gateway; pub mod mixnode; pub mod network_requester; +pub mod openapi; pub mod roles; pub(crate) mod routes { @@ -39,4 +40,5 @@ pub(super) fn routes(config: Config) -> Router { ) .route(routes::BUILD_INFO, get(build_info)) .route(routes::ROLES, get(roles)) + .merge(openapi::route()) } diff --git a/nym-node/src/http/router/api/v1/openapi.rs b/nym-node/src/http/router/api/v1/openapi.rs new file mode 100644 index 0000000000..cd1fb53891 --- /dev/null +++ b/nym-node/src/http/router/api/v1/openapi.rs @@ -0,0 +1,19 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use axum::Router; +use utoipa::OpenApi; +use utoipa_swagger_ui::SwaggerUi; + +#[derive(OpenApi)] +#[openapi(info(title = "NymNode API"))] +pub(crate) struct ApiDoc; + +pub(crate) fn route() -> Router { + // provide absolute path to the openapi.json + let config = utoipa_swagger_ui::Config::from("/api/v1/api-docs/openapi.json"); + SwaggerUi::new("/swagger") + .url("/api-docs/openapi.json", ApiDoc::openapi()) + .config(config) + .into() +} diff --git a/nym-node/src/http/router/mod.rs b/nym-node/src/http/router/mod.rs index e68b3de469..81b212e4e7 100644 --- a/nym-node/src/http/router/mod.rs +++ b/nym-node/src/http/router/mod.rs @@ -37,6 +37,11 @@ pub struct NymNodeRouter { impl NymNodeRouter { pub fn new(config: Config) -> NymNodeRouter { + /* + .merge(SwaggerUi::new("/swagger-ui") + .url("/api-docs/openapi.json", ApiDoc::openapi())); + */ + use utoipa::OpenApi; NymNodeRouter { inner: Router::new() .nest(routes::LANDING_PAGE, landing_page::routes(config.landing))