27a8619
use axum::http::{Response, StatusCode};
use utoipa::{Modify, OpenApi};
use utoipa_scalar::{Scalar, Servable};
use once_cell::sync::Lazy;
use crate::{health, router::API_PREFIX};
/// Root OpenAPI document that only carries the health endpoints.
///
/// The per-domain documents are merged at runtime by [`openapi`] so that every
/// path keeps its absolute form (e.g. `/issues/{channel_id}`) before the
/// unified [`API_PREFIX`] is applied.
#[derive(OpenApi)]
#[openapi(
info(
title = "Untitled API",
description = "Unified HTTP API for the untitled platform",
version = "1.94.0"
),
paths(health::liveness, health::readiness)
)]
struct WebapiApiDoc;
/// Build the merged OpenAPI document with every path prefixed by [`API_PREFIX`].
pub fn openapi() -> utoipa::openapi::OpenApi {
let mut doc = export::openapi_concat!(
WebapiApiDoc,
auth::handler::AuthApiDoc,
issues::IssuesApiDoc,
project::ProjectApiDoc,
repo::handler::openapi::ApiDoc,
space::SpaceApiDoc,
user::UserApiDoc
);
export::openapi::PrefixModifier {
prefix: API_PREFIX.to_owned(),
}
.modify(&mut doc);
doc
}
static DOCS_HTML: Lazy<String> = Lazy::new(|| {
Scalar::with_url("/api-docs", openapi()).to_html()
});
pub async fn docs() -> Response<String> {
Response::builder()
.status(StatusCode::OK)
.header("Content-Type", "text/html")
.body(DOCS_HTML.clone())
.expect("Failed to build response")
}