aboutsummaryrefslogtreecommitdiffstats
path: root/crates
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2025-08-08 15:13:17 +0200
committerrtkay123 <dev@kanjala.com>2025-08-08 15:13:17 +0200
commit0f663ccb94581264e839bab9ae386114e8bd9973 (patch)
tree3e9794117a1e8d41c7789b2efb74dfc5684caafc /crates
parent7f38c6ad7d3e140b6f270f80128def938c0659d5 (diff)
downloadwarden-0f663ccb94581264e839bab9ae386114e8bd9973.tar.bz2
warden-0f663ccb94581264e839bab9ae386114e8bd9973.zip
feat(warden): openapi
Diffstat (limited to 'crates')
-rw-r--r--crates/warden/Cargo.toml15
-rw-r--r--crates/warden/src/server.rs51
-rw-r--r--crates/warden/src/server/routes.rs19
-rw-r--r--crates/warden/src/server/routes/processor.rs11
-rw-r--r--crates/warden/src/server/routes/processor/pacs008.rs35
-rw-r--r--crates/warden/src/version.rs3
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,
}