diff options
author | rtkay123 <dev@kanjala.com> | 2025-08-08 15:13:17 +0200 |
---|---|---|
committer | rtkay123 <dev@kanjala.com> | 2025-08-08 15:13:17 +0200 |
commit | 0f663ccb94581264e839bab9ae386114e8bd9973 (patch) | |
tree | 3e9794117a1e8d41c7789b2efb74dfc5684caafc /crates | |
parent | 7f38c6ad7d3e140b6f270f80128def938c0659d5 (diff) | |
download | warden-0f663ccb94581264e839bab9ae386114e8bd9973.tar.bz2 warden-0f663ccb94581264e839bab9ae386114e8bd9973.zip |
feat(warden): openapi
Diffstat (limited to 'crates')
-rw-r--r-- | crates/warden/Cargo.toml | 15 | ||||
-rw-r--r-- | crates/warden/src/server.rs | 51 | ||||
-rw-r--r-- | crates/warden/src/server/routes.rs | 19 | ||||
-rw-r--r-- | crates/warden/src/server/routes/processor.rs | 11 | ||||
-rw-r--r-- | crates/warden/src/server/routes/processor/pacs008.rs | 35 | ||||
-rw-r--r-- | crates/warden/src/version.rs | 3 |
6 files changed, 123 insertions, 11 deletions
diff --git a/crates/warden/Cargo.toml b/crates/warden/Cargo.toml index c50271e..20c646b 100644 --- a/crates/warden/Cargo.toml +++ b/crates/warden/Cargo.toml @@ -16,7 +16,20 @@ serde = { workspace = true, features = ["derive"] } serde_json.workspace = true tokio = { workspace = true, features = ["macros", "rt-multi-thread", "signal"] } tracing.workspace = true -warden-core = { workspace = true, features = ["iso20022"] } +utoipa = { workspace = true, features = ["axum_extras"] } +utoipa-axum.workspace = true +utoipa-rapidoc = { workspace = true, optional = true } +utoipa-redoc = { workspace = true, optional = true } +utoipa-scalar = { workspace = true, optional = true } +utoipa-swagger-ui = { workspace = true, optional = true } +warden-core = { workspace = true, features = ["iso20022", "openapi"] } + +[features] +# default = [] +swagger = ["dep:utoipa-swagger-ui", "utoipa-swagger-ui/axum"] +redoc = ["dep:utoipa-redoc", "utoipa-redoc/axum"] +rapidoc = ["dep:utoipa-rapidoc", "utoipa-rapidoc/axum"] +scalar = ["dep:utoipa-scalar", "utoipa-scalar/axum"] [dev-dependencies] tower = { workspace = true, features = ["util"] } diff --git a/crates/warden/src/server.rs b/crates/warden/src/server.rs index c53b4bb..a1968bb 100644 --- a/crates/warden/src/server.rs +++ b/crates/warden/src/server.rs @@ -1,11 +1,56 @@ mod routes; -use axum::{Router, routing::get}; +use axum::Router; +use utoipa::OpenApi; +use utoipa_axum::{router::OpenApiRouter, routes}; -use crate::state::AppHandle; +#[cfg(feature = "redoc")] +use utoipa_redoc::Servable; +#[cfg(feature = "scalar")] +use utoipa_scalar::Servable as _; + +use crate::{server::routes::ApiDoc, state::AppHandle}; pub fn router(state: AppHandle) -> Router { - Router::new().route("/", get(routes::health_check)) + let (router, api) = OpenApiRouter::with_openapi(ApiDoc::openapi()) + .routes(routes!(health_check)) + .nest("/api", routes::processor::router(state.clone())) + .split_for_parts(); + + #[cfg(feature = "swagger")] + let router = router.merge( + utoipa_swagger_ui::SwaggerUi::new("/swagger-ui") + .url("/api-docs/swaggerdoc.json", api.clone()), + ); + + #[cfg(feature = "redoc")] + let router = router.merge(utoipa_redoc::Redoc::with_url("/redoc", api.clone())); + + #[cfg(feature = "rapidoc")] + let router = router.merge( + utoipa_rapidoc::RapiDoc::with_openapi("/api-docs/rapidoc.json", api.clone()) + .path("/rapidoc"), + ); + + #[cfg(feature = "scalar")] + let router = router.merge(utoipa_scalar::Scalar::with_url("/scalar", api)); + + router +} + +/// Get health of the API. +#[utoipa::path( + method(get), + path = "/", + responses( + (status = OK, description = "Success", body = str, content_type = "text/plain") + ) +)] +pub async fn health_check() -> impl axum::response::IntoResponse { + let name = env!("CARGO_PKG_NAME"); + let ver = env!("CARGO_PKG_VERSION"); + + format!("{name} v{ver} is live") } #[cfg(test)] diff --git a/crates/warden/src/server/routes.rs b/crates/warden/src/server/routes.rs index ea877e6..771784b 100644 --- a/crates/warden/src/server/routes.rs +++ b/crates/warden/src/server/routes.rs @@ -1,11 +1,18 @@ -use axum::response::IntoResponse; +pub mod processor; -pub async fn health_check() -> impl IntoResponse { - let name = env!("CARGO_PKG_NAME"); - let ver = env!("CARGO_PKG_VERSION"); +use utoipa::OpenApi; - format!("{name} v{ver} is live") -} +const PACS008_001_12: &str = "pacs.008.001.12"; +const PACS002_001_12: &str = "pacs.002.001.12"; + +#[derive(OpenApi)] +#[openapi( + tags( + (name = PACS008_001_12, description = "Submit a pacs.008.001.12 payload"), + (name = PACS002_001_12, description = "Submit a pacs.002.001.12 payload"), + ) +)] +pub struct ApiDoc; #[cfg(test)] mod tests { diff --git a/crates/warden/src/server/routes/processor.rs b/crates/warden/src/server/routes/processor.rs new file mode 100644 index 0000000..d1f062a --- /dev/null +++ b/crates/warden/src/server/routes/processor.rs @@ -0,0 +1,11 @@ +mod pacs008; + +use utoipa_axum::{router::OpenApiRouter, routes}; + +use crate::state::AppHandle; + +pub fn router(store: AppHandle) -> OpenApiRouter { + OpenApiRouter::new() + .routes(routes!(pacs008::post_pacs008)) + .with_state(store) +} diff --git a/crates/warden/src/server/routes/processor/pacs008.rs b/crates/warden/src/server/routes/processor/pacs008.rs new file mode 100644 index 0000000..cde5c07 --- /dev/null +++ b/crates/warden/src/server/routes/processor/pacs008.rs @@ -0,0 +1,35 @@ +use axum::{extract::State, response::IntoResponse}; +use warden_core::iso20022::pacs008::Pacs008Document; + +use crate::{error::AppError, server::routes::PACS008_001_12, state::AppHandle, version::Version}; + +/// Submit a pacs.008.001.12 transaction +#[utoipa::path( + post, + responses(( + status = CREATED, + body = Pacs008Document + )), + operation_id = "post_pacs_008", // https://github.com/juhaku/utoipa/issues/1170 + path = "/{version}/pacs008", + params( + ("version" = Version, Path, description = "API version, e.g., v1, v2, v3") + ), + tag = PACS008_001_12, + request_body( + content = Pacs008Document + )) +] +#[axum::debug_handler] +#[tracing::instrument( + skip(state, transaction), + err(Debug), + fields(method = "POST", end_to_end_id, msg_id, tx_tp) +)] +pub(super) async fn post_pacs008( + version: Version, + State(state): State<AppHandle>, + axum::Json(transaction): axum::Json<Pacs008Document>, +) -> Result<impl IntoResponse, AppError> { + Ok(String::default()) +} diff --git a/crates/warden/src/version.rs b/crates/warden/src/version.rs index 966d694..4eb5677 100644 --- a/crates/warden/src/version.rs +++ b/crates/warden/src/version.rs @@ -6,8 +6,9 @@ use axum::{ http::{StatusCode, request::Parts}, response::{IntoResponse, Response}, }; +use utoipa::ToSchema; -#[derive(Debug)] +#[derive(Debug, ToSchema)] pub enum Version { V0, } |