diff options
author | Toby Vincent <tobyv@tobyvin.dev> | 2024-09-26 17:31:16 -0500 |
---|---|---|
committer | Toby Vincent <tobyv@tobyvin.dev> | 2024-09-26 17:31:16 -0500 |
commit | fd992d7e3c03f37fbcafe9d3f26c72a2ead3b2a7 (patch) | |
tree | f3e29427d1bbe4a8d6e050abbd9f66afb5fa2152 /src/api.rs | |
parent | cbfca14b38806798847e3f2008038b25194a9b8b (diff) |
feat!: impl full api
Diffstat (limited to 'src/api.rs')
-rw-r--r-- | src/api.rs | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/api.rs b/src/api.rs new file mode 100644 index 0000000..e6a91ba --- /dev/null +++ b/src/api.rs @@ -0,0 +1,73 @@ +use std::collections::HashMap; + +use axum::{extract::State, response::IntoResponse, Json}; +use serde::{Deserialize, Serialize}; + +use crate::{service::Services, Check, Error, Status}; + +pub mod services; + +pub fn router() -> axum::Router<Services> { + use axum::routing::get; + + axum::Router::new() + .route("/healthcheck", get(healthcheck)) + .merge(services::router()) + .fallback(fallback) +} + +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct Health { + pub status: Status, + pub output: Option<String>, + pub checks: HashMap<String, Check>, +} + +impl<T: std::error::Error> From<T> for Health { + fn from(value: T) -> Self { + Health { + status: Status::Fail, + output: Some(value.to_string()), + ..Default::default() + } + } +} + +impl IntoResponse for Health { + fn into_response(self) -> axum::response::Response { + Json(self).into_response() + } +} + +pub async fn healthcheck(State(services): State<Services>) -> Health { + let checks = match services.check().await { + Ok(c) => c, + Err(err) => { + return Health { + status: Status::Fail, + output: Some(err.to_string()), + ..Default::default() + } + } + }; + + let (status, output) = match checks + .values() + .filter(|s| !matches!(s.status, Status::Pass)) + .count() + { + 0 => (Status::Pass, None), + 1 => (Status::Fail, Some("1 issue detected".to_string())), + n => (Status::Fail, Some(format!("{n} issues detected"))), + }; + + Health { + status, + output, + checks, + } +} + +pub async fn fallback(uri: axum::http::Uri) -> Error { + Error::RouteNotFound(uri) +} |