b9acc03761
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
63 lines
1.7 KiB
Rust
63 lines
1.7 KiB
Rust
use axum::{Json, Router, extract::State, http::StatusCode, response::IntoResponse, routing::get};
|
|
use serde::Serialize;
|
|
use utoipa::ToSchema;
|
|
|
|
use crate::AppState;
|
|
|
|
/// Liveness payload: the process is running.
|
|
#[derive(Serialize, ToSchema)]
|
|
pub(crate) struct Live {
|
|
/// Always `"ok"` when the process serves requests.
|
|
pub status: &'static str,
|
|
}
|
|
|
|
/// Readiness payload: dependencies were checked.
|
|
#[derive(Serialize, ToSchema)]
|
|
pub(crate) struct Ready {
|
|
/// `"ok"` when ready, `"degraded"` otherwise.
|
|
pub status: &'static str,
|
|
/// Whether the database responded to a ping.
|
|
pub database: bool,
|
|
}
|
|
|
|
/// Liveness probe — no dependencies checked.
|
|
#[utoipa::path(get, path = "/health/live", responses((status = 200, body = Live)))]
|
|
pub(crate) async fn live() -> Json<Live> {
|
|
Json(Live { status: "ok" })
|
|
}
|
|
|
|
/// Readiness probe — confirms the database answers.
|
|
#[utoipa::path(
|
|
get,
|
|
path = "/health/ready",
|
|
responses(
|
|
(status = 200, body = Ready, description = "Ready"),
|
|
(status = 503, body = Ready, description = "A dependency is unavailable")
|
|
)
|
|
)]
|
|
pub(crate) async fn ready(State(state): State<AppState>) -> impl IntoResponse {
|
|
match state.db.ping().await {
|
|
Ok(()) => (
|
|
StatusCode::OK,
|
|
Json(Ready {
|
|
status: "ok",
|
|
database: true,
|
|
}),
|
|
),
|
|
Err(_) => (
|
|
StatusCode::SERVICE_UNAVAILABLE,
|
|
Json(Ready {
|
|
status: "degraded",
|
|
database: false,
|
|
}),
|
|
),
|
|
}
|
|
}
|
|
|
|
/// Health routes, parameterized over [`AppState`].
|
|
pub(crate) fn routes() -> Router<AppState> {
|
|
Router::new()
|
|
.route("/health/live", get(live))
|
|
.route("/health/ready", get(ready))
|
|
}
|