From e550c65257a5c52a2c7e556c25fd803373d65b48 Mon Sep 17 00:00:00 2001 From: HTGAzureX1212 <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:20:55 +0800 Subject: [PATCH 1/7] change: init migration to GET for getting uptime --- api-backend/hartex-backend-driver/src/main.rs | 2 +- .../hartex-backend-routes/src/uptime.rs | 68 +++++++++---------- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/api-backend/hartex-backend-driver/src/main.rs b/api-backend/hartex-backend-driver/src/main.rs index 4e2ddee57..688107eb4 100644 --- a/api-backend/hartex-backend-driver/src/main.rs +++ b/api-backend/hartex-backend-driver/src/main.rs @@ -83,7 +83,7 @@ pub async fn main() -> miette::Result<()> { .layer(TimeoutLayer::new(Duration::from_secs(30))) .route( "/api/:version/stats/uptime", - post(hartex_backend_routes::uptime::post_uptime) + post(hartex_backend_routes::uptime::get_uptime) .patch(hartex_backend_routes::uptime::patch_uptime), ) .with_state(pool); diff --git a/api-backend/hartex-backend-routes/src/uptime.rs b/api-backend/hartex-backend-routes/src/uptime.rs index 9dde32945..df8a5a59c 100644 --- a/api-backend/hartex-backend-routes/src/uptime.rs +++ b/api-backend/hartex-backend-routes/src/uptime.rs @@ -41,18 +41,17 @@ use hartex_database_queries::api_backend::queries::start_timestamp_upsert::start use time::OffsetDateTime; use hartex_log::log; -/// # `PATCH /stats/uptime` +/// # `GET /stats/uptime` /// -/// Update the uptime of a certain component. -#[allow(clippy::cast_possible_truncation)] +/// Obtain the uptime of a certain component. #[allow(clippy::cast_sign_loss)] #[allow(clippy::missing_panics_doc)] // this function cannot panic #[allow(clippy::module_name_repetitions)] -pub async fn patch_uptime( +pub async fn get_uptime( _: APIVersion, State(pool): State>>, - Json(query): Json, -) -> (StatusCode, Json>) { + Json(query): Json, +) -> (StatusCode, Json>) { log::trace!("retrieving connection from database pool"); let result = pool.get().await; if result.is_err() { @@ -65,43 +64,43 @@ pub async fn patch_uptime( let connection = result.unwrap(); let client = connection.client(); - log::trace!("updating timestamp"); - let Ok(timestamp) = OffsetDateTime::from_unix_timestamp(query.start_timestamp() as i64) else { - // FIXME: return a better status code as the timestamp is out of range if this branch is reached - // just 500 for now - return ( - StatusCode::INTERNAL_SERVER_ERROR, - Response::internal_server_error(), - ); - }; - let result = start_timestamp_upsert() - .bind(client, &query.component_name(), ×tamp) + log::trace!("querying timestamp"); + let result = select_start_timestamp_by_component() + .bind(client, &query.component_name()) + .one() .await; + // FIXME: figure out whether the data is actually not found and return 404 if result.is_err() { + log::error!("{:?}", result.unwrap_err()); + return ( StatusCode::INTERNAL_SERVER_ERROR, Response::internal_server_error(), ); } + let data = result.unwrap(); ( StatusCode::OK, - Response::ok(()), + Response::ok(UptimeResponse::with_start_timestamp( + data.timestamp.unix_timestamp() as u128, + )), ) } -/// # `POST /stats/uptime` +/// # `PATCH /stats/uptime` /// -/// Obtain the uptime of a certain component. +/// Update the uptime of a certain component. +#[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_sign_loss)] #[allow(clippy::missing_panics_doc)] // this function cannot panic #[allow(clippy::module_name_repetitions)] -pub async fn post_uptime( +pub async fn patch_uptime( _: APIVersion, State(pool): State>>, - Json(query): Json, -) -> (StatusCode, Json>) { + Json(query): Json, +) -> (StatusCode, Json>) { log::trace!("retrieving connection from database pool"); let result = pool.get().await; if result.is_err() { @@ -114,27 +113,28 @@ pub async fn post_uptime( let connection = result.unwrap(); let client = connection.client(); - log::trace!("querying timestamp"); - let result = select_start_timestamp_by_component() - .bind(client, &query.component_name()) - .one() + log::trace!("updating timestamp"); + let Ok(timestamp) = OffsetDateTime::from_unix_timestamp(query.start_timestamp() as i64) else { + // FIXME: return a better status code as the timestamp is out of range if this branch is reached + // just 500 for now + return ( + StatusCode::INTERNAL_SERVER_ERROR, + Response::internal_server_error(), + ); + }; + let result = start_timestamp_upsert() + .bind(client, &query.component_name(), ×tamp) .await; - // FIXME: figure out whether the data is actually not found and return 404 if result.is_err() { - log::error!("{:?}", result.unwrap_err()); - return ( StatusCode::INTERNAL_SERVER_ERROR, Response::internal_server_error(), ); } - let data = result.unwrap(); ( StatusCode::OK, - Response::ok(UptimeResponse::with_start_timestamp( - data.timestamp.unix_timestamp() as u128, - )), + Response::ok(()), ) } From f6907d62575af50a21f73c03ffacb11565eef0e4 Mon Sep 17 00:00:00 2001 From: HTGAzureX1212 <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:25:38 +0800 Subject: [PATCH 2/7] use get instead --- api-backend/hartex-backend-driver/src/main.rs | 4 ++-- api-backend/hartex-backend-models/src/uptime.rs | 8 ++++---- api-backend/hartex-backend-routes/src/uptime.rs | 3 ++- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/api-backend/hartex-backend-driver/src/main.rs b/api-backend/hartex-backend-driver/src/main.rs index 688107eb4..0f02f0c59 100644 --- a/api-backend/hartex-backend-driver/src/main.rs +++ b/api-backend/hartex-backend-driver/src/main.rs @@ -36,7 +36,7 @@ use std::env; use std::future; use std::time::Duration; -use axum::routing::post; +use axum::routing::get; use axum::Router; use bb8_postgres::bb8::Pool; use bb8_postgres::tokio_postgres::NoTls; @@ -83,7 +83,7 @@ pub async fn main() -> miette::Result<()> { .layer(TimeoutLayer::new(Duration::from_secs(30))) .route( "/api/:version/stats/uptime", - post(hartex_backend_routes::uptime::get_uptime) + get(hartex_backend_routes::uptime::get_uptime) .patch(hartex_backend_routes::uptime::patch_uptime), ) .with_state(pool); diff --git a/api-backend/hartex-backend-models/src/uptime.rs b/api-backend/hartex-backend-models/src/uptime.rs index 369398104..06444d7e0 100644 --- a/api-backend/hartex-backend-models/src/uptime.rs +++ b/api-backend/hartex-backend-models/src/uptime.rs @@ -31,22 +31,22 @@ use serde::Serialize; #[allow(clippy::module_name_repetitions)] #[derive(Deserialize, Serialize)] pub struct UptimeQuery { - component_name: String, + component: String, } impl UptimeQuery { /// Create a new uptime query with the component name to search for. #[must_use] - pub fn new(component_name: &str) -> Self { + pub fn new(component: &str) -> Self { Self { - component_name: component_name.to_string(), + component: component.to_string(), } } /// The component name to search for in this uptime query. #[must_use] pub fn component_name(&self) -> &str { - self.component_name.as_str() + self.component.as_str() } } diff --git a/api-backend/hartex-backend-routes/src/uptime.rs b/api-backend/hartex-backend-routes/src/uptime.rs index df8a5a59c..9ead752d9 100644 --- a/api-backend/hartex-backend-routes/src/uptime.rs +++ b/api-backend/hartex-backend-routes/src/uptime.rs @@ -24,6 +24,7 @@ /// /// Routes interacting with the uptime API. +use axum::extract::Query; use axum::extract::State; use axum::http::StatusCode; use axum::Json; @@ -50,7 +51,7 @@ use hartex_log::log; pub async fn get_uptime( _: APIVersion, State(pool): State>>, - Json(query): Json, + Query(query): Query, ) -> (StatusCode, Json>) { log::trace!("retrieving connection from database pool"); let result = pool.get().await; From c108aaaadf321067dd6554a260380671290e5061 Mon Sep 17 00:00:00 2001 From: HTGAzureX1212 <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 2 Nov 2024 17:52:34 +0800 Subject: [PATCH 3/7] attempt to add --- api-backend/Cargo.lock | 77 +++++++++++++++---- api-backend/hartex-backend-driver/Cargo.toml | 4 +- api-backend/hartex-backend-driver/src/main.rs | 19 +++-- api-backend/hartex-backend-models/Cargo.toml | 2 + .../hartex-backend-models/src/uptime.rs | 6 +- api-backend/hartex-backend-routes/Cargo.toml | 1 + .../hartex-backend-routes/src/uptime.rs | 8 +- discord-frontend/Cargo.lock | 45 ++++++++++- 8 files changed, 135 insertions(+), 27 deletions(-) diff --git a/api-backend/Cargo.lock b/api-backend/Cargo.lock index 488a1fb7c..b41bccf24 100644 --- a/api-backend/Cargo.lock +++ b/api-backend/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -148,7 +148,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 1.0.1", "tokio", - "tower 0.5.1", + "tower", "tower-layer", "tower-service", "tracing", @@ -714,10 +714,12 @@ dependencies = [ "serde", "serde_json", "tokio", - "tower 0.4.13", + "tower", "tower-http", "tower-service", "tracing", + "utoipa-axum", + "utoipa-redoc", ] [[package]] @@ -731,6 +733,8 @@ dependencies = [ "axum", "hartex_discord_configuration_models", "serde", + "utoipa", + "utoipa-axum", ] [[package]] @@ -744,6 +748,7 @@ dependencies = [ "hartex_log", "serde_json", "time", + "utoipa", ] [[package]] @@ -983,6 +988,7 @@ checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", + "serde", ] [[package]] @@ -1347,6 +1353,12 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -2023,17 +2035,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tower" version = "0.5.1" @@ -2186,6 +2187,54 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "utoipa" +version = "5.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d9ba0ade4e2f024cd1842dfbaf9dbc540639fc082299acf7649d71bd14eaca3" +dependencies = [ + "indexmap 2.5.0", + "serde", + "serde_json", + "utoipa-gen", +] + +[[package]] +name = "utoipa-axum" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1370cc4a8eee751c4d2a729566d83d1568212320a20581c7c72c2d76ab80ed37" +dependencies = [ + "axum", + "paste", + "tower-layer", + "tower-service", + "utoipa", +] + +[[package]] +name = "utoipa-gen" +version = "5.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf390d6503c9c9eac988447c38ba934a707b0b768b14511a493b4fc0e8ecb00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.82", +] + +[[package]] +name = "utoipa-redoc" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9218304bba9a0ea5e92085b0a427ccce5fd56eaaf6436d245b7578e6a95787e1" +dependencies = [ + "axum", + "serde", + "serde_json", + "utoipa", +] + [[package]] name = "version_check" version = "0.9.5" diff --git a/api-backend/hartex-backend-driver/Cargo.toml b/api-backend/hartex-backend-driver/Cargo.toml index 6490d3a71..c0e57c350 100644 --- a/api-backend/hartex-backend-driver/Cargo.toml +++ b/api-backend/hartex-backend-driver/Cargo.toml @@ -25,9 +25,11 @@ miette = { version = "7.2.0", features = ["fancy"] } serde = "1.0.210" serde_json = "1.0.128" tokio = { version = "1.40.0", features = ["full"] } -tower = "0.4.13" +tower = "0.5.1" tower-http = { version = "0.6.1", features = ["timeout", "trace"] } tower-service = "0.3.3" tracing = { version = "0.1.40", features = ["log-always"] } +utoipa-axum = "0.1.2" +utoipa-redoc = { version = "5.0.0", features = ["axum"] } [features] diff --git a/api-backend/hartex-backend-driver/src/main.rs b/api-backend/hartex-backend-driver/src/main.rs index 0f02f0c59..2c6a0f8bf 100644 --- a/api-backend/hartex-backend-driver/src/main.rs +++ b/api-backend/hartex-backend-driver/src/main.rs @@ -37,7 +37,6 @@ use std::future; use std::time::Duration; use axum::routing::get; -use axum::Router; use bb8_postgres::bb8::Pool; use bb8_postgres::tokio_postgres::NoTls; use bb8_postgres::PostgresConnectionManager; @@ -49,6 +48,10 @@ use tokio::net::TcpListener; use tokio::signal; use tower_http::timeout::TimeoutLayer; use tower_http::trace::TraceLayer; +use utoipa_axum::router::OpenApiRouter; +use utoipa_axum::routes; +use utoipa_redoc::Redoc; +use utoipa_redoc::Servable; /// # Entry Point /// @@ -78,21 +81,25 @@ pub async fn main() -> miette::Result<()> { let pool = Pool::builder().build(manager).await.into_diagnostic()?; log::debug!("starting axum server"); - let app = Router::new() + let (app, openapi) = OpenApiRouter::new() .layer(TraceLayer::new_for_http()) .layer(TimeoutLayer::new(Duration::from_secs(30))) .route( "/api/:version/stats/uptime", - get(hartex_backend_routes::uptime::get_uptime) - .patch(hartex_backend_routes::uptime::patch_uptime), + routes![ + hartex_backend_routes::uptime::get_uptime + ], ) - .with_state(pool); + .with_state(pool) + .split_for_parts(); + + let router = app.merge(Redoc::with_url("/openapi", openapi)); let domain = env::var("API_DOMAIN").into_diagnostic()?; let listener = TcpListener::bind(&domain).await.into_diagnostic()?; log::debug!("listening on {domain}"); - axum::serve(listener, app) + axum::serve(listener, router) .with_graceful_shutdown(shutdown()) .await .into_diagnostic()?; diff --git a/api-backend/hartex-backend-models/Cargo.toml b/api-backend/hartex-backend-models/Cargo.toml index a3137e21f..fef091d4c 100644 --- a/api-backend/hartex-backend-models/Cargo.toml +++ b/api-backend/hartex-backend-models/Cargo.toml @@ -15,5 +15,7 @@ hartex_discord_configuration_models = { path = "../../discord-frontend/hartex-di axum = "0.7.7" serde = { version = "1.0.210", features = ["derive"] } +utoipa = "5.1.3" +utoipa-axum = "0.1.2" [features] diff --git a/api-backend/hartex-backend-models/src/uptime.rs b/api-backend/hartex-backend-models/src/uptime.rs index 06444d7e0..ec5d39ddb 100644 --- a/api-backend/hartex-backend-models/src/uptime.rs +++ b/api-backend/hartex-backend-models/src/uptime.rs @@ -26,10 +26,12 @@ use serde::Deserialize; use serde::Serialize; +use utoipa::IntoParams; +use utoipa::ToSchema; /// An uptime query. #[allow(clippy::module_name_repetitions)] -#[derive(Deserialize, Serialize)] +#[derive(Deserialize, IntoParams, Serialize)] pub struct UptimeQuery { component: String, } @@ -52,7 +54,7 @@ impl UptimeQuery { /// A response to an uptime query. #[allow(clippy::module_name_repetitions)] -#[derive(Clone, Deserialize, Serialize)] +#[derive(Clone, Deserialize, Serialize, ToSchema)] pub struct UptimeResponse { start_timestamp: u128, } diff --git a/api-backend/hartex-backend-routes/Cargo.toml b/api-backend/hartex-backend-routes/Cargo.toml index 33e9474ec..92301a57f 100644 --- a/api-backend/hartex-backend-routes/Cargo.toml +++ b/api-backend/hartex-backend-routes/Cargo.toml @@ -21,5 +21,6 @@ axum = { version = "0.7.7", features = ["json", "macros"] } bb8-postgres = "0.8.1" serde_json = "1.0.128" time = "0.3.36" +utoipa = "5.1.3" [features] diff --git a/api-backend/hartex-backend-routes/src/uptime.rs b/api-backend/hartex-backend-routes/src/uptime.rs index 9ead752d9..3ff93b76f 100644 --- a/api-backend/hartex-backend-routes/src/uptime.rs +++ b/api-backend/hartex-backend-routes/src/uptime.rs @@ -39,8 +39,8 @@ use hartex_backend_models::APIVersion; use hartex_backend_models::Response; use hartex_database_queries::api_backend::queries::start_timestamp_select_by_component::select_start_timestamp_by_component; use hartex_database_queries::api_backend::queries::start_timestamp_upsert::start_timestamp_upsert; -use time::OffsetDateTime; use hartex_log::log; +use time::OffsetDateTime; /// # `GET /stats/uptime` /// @@ -48,6 +48,12 @@ use hartex_log::log; #[allow(clippy::cast_sign_loss)] #[allow(clippy::missing_panics_doc)] // this function cannot panic #[allow(clippy::module_name_repetitions)] +#[utoipa::path( + get, + path = "/stats/uptime", + params(UptimeQuery), + responses((status = 200, description = "Uptime retrieved successfully", body = UptimeResponse)) +)] pub async fn get_uptime( _: APIVersion, State(pool): State>>, diff --git a/discord-frontend/Cargo.lock b/discord-frontend/Cargo.lock index 5b9c98b31..bf2dd12f4 100644 --- a/discord-frontend/Cargo.lock +++ b/discord-frontend/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -1162,6 +1162,8 @@ dependencies = [ "axum", "hartex_discord_configuration_models", "serde", + "utoipa", + "utoipa-axum", ] [[package]] @@ -1862,6 +1864,7 @@ checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown 0.14.5", + "serde", ] [[package]] @@ -1988,7 +1991,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -4058,6 +4061,42 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "utoipa" +version = "5.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d9ba0ade4e2f024cd1842dfbaf9dbc540639fc082299acf7649d71bd14eaca3" +dependencies = [ + "indexmap 2.5.0", + "serde", + "serde_json", + "utoipa-gen", +] + +[[package]] +name = "utoipa-axum" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1370cc4a8eee751c4d2a729566d83d1568212320a20581c7c72c2d76ab80ed37" +dependencies = [ + "axum", + "paste", + "tower-layer", + "tower-service", + "utoipa", +] + +[[package]] +name = "utoipa-gen" +version = "5.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf390d6503c9c9eac988447c38ba934a707b0b768b14511a493b4fc0e8ecb00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.86", +] + [[package]] name = "vcpkg" version = "0.2.15" @@ -4283,7 +4322,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] From d46853ad2fe7bd8c9aea45cba98425bf1d0a0b79 Mon Sep 17 00:00:00 2001 From: HTGAzureX1212 <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 2 Nov 2024 18:24:04 +0800 Subject: [PATCH 4/7] fix errors --- api-backend/Cargo.lock | 1 + api-backend/hartex-backend-driver/Cargo.toml | 1 + api-backend/hartex-backend-driver/src/main.rs | 10 +++------- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/api-backend/Cargo.lock b/api-backend/Cargo.lock index b41bccf24..15721d57d 100644 --- a/api-backend/Cargo.lock +++ b/api-backend/Cargo.lock @@ -718,6 +718,7 @@ dependencies = [ "tower-http", "tower-service", "tracing", + "utoipa", "utoipa-axum", "utoipa-redoc", ] diff --git a/api-backend/hartex-backend-driver/Cargo.toml b/api-backend/hartex-backend-driver/Cargo.toml index c0e57c350..a93eac3c2 100644 --- a/api-backend/hartex-backend-driver/Cargo.toml +++ b/api-backend/hartex-backend-driver/Cargo.toml @@ -29,6 +29,7 @@ tower = "0.5.1" tower-http = { version = "0.6.1", features = ["timeout", "trace"] } tower-service = "0.3.3" tracing = { version = "0.1.40", features = ["log-always"] } +utoipa = "5.1.3" utoipa-axum = "0.1.2" utoipa-redoc = { version = "5.0.0", features = ["axum"] } diff --git a/api-backend/hartex-backend-driver/src/main.rs b/api-backend/hartex-backend-driver/src/main.rs index 2c6a0f8bf..fde947157 100644 --- a/api-backend/hartex-backend-driver/src/main.rs +++ b/api-backend/hartex-backend-driver/src/main.rs @@ -36,7 +36,6 @@ use std::env; use std::future; use std::time::Duration; -use axum::routing::get; use bb8_postgres::bb8::Pool; use bb8_postgres::tokio_postgres::NoTls; use bb8_postgres::PostgresConnectionManager; @@ -84,12 +83,9 @@ pub async fn main() -> miette::Result<()> { let (app, openapi) = OpenApiRouter::new() .layer(TraceLayer::new_for_http()) .layer(TimeoutLayer::new(Duration::from_secs(30))) - .route( - "/api/:version/stats/uptime", - routes![ - hartex_backend_routes::uptime::get_uptime - ], - ) + .routes(routes!( + hartex_backend_routes::uptime::get_uptime + )) .with_state(pool) .split_for_parts(); From 81a8c1c7004bd526858ee312ea87a6869778d8e1 Mon Sep 17 00:00:00 2001 From: HTGAzureX1212 <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 2 Nov 2024 20:43:18 +0800 Subject: [PATCH 5/7] add utoipa API docs --- api-backend/Cargo.lock | 8 ++++---- api-backend/hartex-backend-driver/Cargo.toml | 2 +- api-backend/hartex-backend-driver/src/main.rs | 5 ++--- database/hartex-database-migrate/build.rs | 4 ++-- database/hartex-database-queries/build.rs | 6 +++--- localization/hartex-localization-core/build.rs | 2 +- tools/bootstrap/build.rs | 2 +- tools/testsuite/build.rs | 2 +- 8 files changed, 15 insertions(+), 16 deletions(-) diff --git a/api-backend/Cargo.lock b/api-backend/Cargo.lock index 15721d57d..42f2368fd 100644 --- a/api-backend/Cargo.lock +++ b/api-backend/Cargo.lock @@ -720,7 +720,7 @@ dependencies = [ "tracing", "utoipa", "utoipa-axum", - "utoipa-redoc", + "utoipa-scalar", ] [[package]] @@ -2225,10 +2225,10 @@ dependencies = [ ] [[package]] -name = "utoipa-redoc" -version = "5.0.0" +name = "utoipa-scalar" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9218304bba9a0ea5e92085b0a427ccce5fd56eaaf6436d245b7578e6a95787e1" +checksum = "c1291aa7a2223c2f8399d1c6627ca0ba57ca0d7ecac762a2094a9dfd6376445a" dependencies = [ "axum", "serde", diff --git a/api-backend/hartex-backend-driver/Cargo.toml b/api-backend/hartex-backend-driver/Cargo.toml index a93eac3c2..dabdfef8d 100644 --- a/api-backend/hartex-backend-driver/Cargo.toml +++ b/api-backend/hartex-backend-driver/Cargo.toml @@ -31,6 +31,6 @@ tower-service = "0.3.3" tracing = { version = "0.1.40", features = ["log-always"] } utoipa = "5.1.3" utoipa-axum = "0.1.2" -utoipa-redoc = { version = "5.0.0", features = ["axum"] } +utoipa-scalar = { version = "0.2.0", features = ["axum"] } [features] diff --git a/api-backend/hartex-backend-driver/src/main.rs b/api-backend/hartex-backend-driver/src/main.rs index fde947157..ae698af0b 100644 --- a/api-backend/hartex-backend-driver/src/main.rs +++ b/api-backend/hartex-backend-driver/src/main.rs @@ -49,8 +49,7 @@ use tower_http::timeout::TimeoutLayer; use tower_http::trace::TraceLayer; use utoipa_axum::router::OpenApiRouter; use utoipa_axum::routes; -use utoipa_redoc::Redoc; -use utoipa_redoc::Servable; +use utoipa_scalar::{Scalar, Servable}; /// # Entry Point /// @@ -89,7 +88,7 @@ pub async fn main() -> miette::Result<()> { .with_state(pool) .split_for_parts(); - let router = app.merge(Redoc::with_url("/openapi", openapi)); + let router = app.merge(Scalar::with_url("/openapi", openapi)); let domain = env::var("API_DOMAIN").into_diagnostic()?; let listener = TcpListener::bind(&domain).await.into_diagnostic()?; diff --git a/database/hartex-database-migrate/build.rs b/database/hartex-database-migrate/build.rs index 2c42f13da..5b9b08223 100644 --- a/database/hartex-database-migrate/build.rs +++ b/database/hartex-database-migrate/build.rs @@ -21,6 +21,6 @@ */ pub fn main() { - println!("cargo:rerun-if-changed=api-backend-migrations"); - println!("cargo:rerun-if-changed=discord-frontend-migrations"); + println!("cargo::rerun-if-changed=api-backend-migrations"); + println!("cargo::rerun-if-changed=discord-frontend-migrations"); } diff --git a/database/hartex-database-queries/build.rs b/database/hartex-database-queries/build.rs index 3cc13405f..51132131d 100644 --- a/database/hartex-database-queries/build.rs +++ b/database/hartex-database-queries/build.rs @@ -32,7 +32,7 @@ pub fn main() { } let api_backend_queries_path = "queries/api_backend"; - println!("cargo:rerun-if-changed={api_backend_queries_path}"); + println!("cargo::rerun-if-changed={api_backend_queries_path}"); let url = env::var("API_PGSQL_URL").unwrap(); cornucopia::generate_live( @@ -47,7 +47,7 @@ pub fn main() { .unwrap(); let configuration_queries_path = "queries/configuration"; - println!("cargo:rerun-if-changed={configuration_queries_path}"); + println!("cargo::rerun-if-changed={configuration_queries_path}"); let url = env::var("HARTEX_NIGHTLY_PGSQL_URL").unwrap(); cornucopia::generate_live( @@ -62,7 +62,7 @@ pub fn main() { .unwrap(); let discord_frontend_queries_path = "queries/discord_frontend"; - println!("cargo:rerun-if-changed={discord_frontend_queries_path}"); + println!("cargo::rerun-if-changed={discord_frontend_queries_path}"); let url = env::var("HARTEX_NIGHTLY_PGSQL_URL").unwrap(); cornucopia::generate_live( diff --git a/localization/hartex-localization-core/build.rs b/localization/hartex-localization-core/build.rs index 30ed7da29..36804fb77 100644 --- a/localization/hartex-localization-core/build.rs +++ b/localization/hartex-localization-core/build.rs @@ -21,5 +21,5 @@ */ pub fn main() { - println!("cargo:rerun-if-changed=../locales"); + println!("cargo::rerun-if-changed=../locales"); } diff --git a/tools/bootstrap/build.rs b/tools/bootstrap/build.rs index 9a3a26017..5f5acab9e 100644 --- a/tools/bootstrap/build.rs +++ b/tools/bootstrap/build.rs @@ -25,5 +25,5 @@ use std::env; pub fn main() { let target = env::var("TARGET").expect("cannot find build target"); - println!("cargo:rustc-env=BOOTSTRAP_TARGET={target}"); + println!("cargo::rustc-env=BOOTSTRAP_TARGET={target}"); } diff --git a/tools/testsuite/build.rs b/tools/testsuite/build.rs index 44ee884a4..59e9595ec 100644 --- a/tools/testsuite/build.rs +++ b/tools/testsuite/build.rs @@ -25,5 +25,5 @@ use std::env; pub fn main() { let target = env::var("TARGET").expect("cannot find build target"); - println!("cargo:rustc-env=TESTSUITE_TARGET={target}"); + println!("cargo::rustc-env=TESTSUITE_TARGET={target}"); } From 3012f3da4e0c330dedff08d0c35bfe739fc52e82 Mon Sep 17 00:00:00 2001 From: HTGAzureX1212 <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 2 Nov 2024 21:33:29 +0800 Subject: [PATCH 6/7] use scalar as docs --- api-backend/hartex-backend-driver/src/main.rs | 15 ++++--- api-backend/hartex-backend-models/src/lib.rs | 39 ------------------- .../hartex-backend-routes/src/uptime.rs | 9 +---- 3 files changed, 11 insertions(+), 52 deletions(-) diff --git a/api-backend/hartex-backend-driver/src/main.rs b/api-backend/hartex-backend-driver/src/main.rs index ae698af0b..1fb9d176e 100644 --- a/api-backend/hartex-backend-driver/src/main.rs +++ b/api-backend/hartex-backend-driver/src/main.rs @@ -47,9 +47,11 @@ use tokio::net::TcpListener; use tokio::signal; use tower_http::timeout::TimeoutLayer; use tower_http::trace::TraceLayer; +use utoipa::openapi::Info; use utoipa_axum::router::OpenApiRouter; use utoipa_axum::routes; -use utoipa_scalar::{Scalar, Servable}; +use utoipa_scalar::Scalar; +use utoipa_scalar::Servable; /// # Entry Point /// @@ -79,7 +81,7 @@ pub async fn main() -> miette::Result<()> { let pool = Pool::builder().build(manager).await.into_diagnostic()?; log::debug!("starting axum server"); - let (app, openapi) = OpenApiRouter::new() + let (app, mut openapi) = OpenApiRouter::new() .layer(TraceLayer::new_for_http()) .layer(TimeoutLayer::new(Duration::from_secs(30))) .routes(routes!( @@ -88,11 +90,12 @@ pub async fn main() -> miette::Result<()> { .with_state(pool) .split_for_parts(); - let router = app.merge(Scalar::with_url("/openapi", openapi)); - let domain = env::var("API_DOMAIN").into_diagnostic()?; let listener = TcpListener::bind(&domain).await.into_diagnostic()?; - log::debug!("listening on {domain}"); + log::debug!("listening on {}", &domain); + + openapi.info = Info::new("HarTex API", env!("CARGO_PKG_VERSION")); + let router = app.merge(Scalar::with_url("/openapi", openapi)); axum::serve(listener, router) .with_graceful_shutdown(shutdown()) @@ -120,7 +123,7 @@ async fn shutdown() { .recv() .await; }; - + #[cfg(not(unix))] let terminate = future::pending::<()>(); diff --git a/api-backend/hartex-backend-models/src/lib.rs b/api-backend/hartex-backend-models/src/lib.rs index dce29e49e..7f3c899df 100644 --- a/api-backend/hartex-backend-models/src/lib.rs +++ b/api-backend/hartex-backend-models/src/lib.rs @@ -28,52 +28,13 @@ #![deny(unsafe_code)] #![deny(warnings)] -use std::collections::HashMap; - -use axum::async_trait; -use axum::extract::FromRequestParts; -use axum::extract::Path; -use axum::http::request::Parts; -use axum::http::StatusCode; -use axum::response::IntoResponse; -use axum::response::Response as AxumResponse; use axum::Json; -use axum::RequestPartsExt; use serde::Deserialize; use serde::Serialize; pub use hartex_discord_configuration_models as config; pub mod uptime; -/// Specifies the API version to be used for a given API request. -#[derive(Copy, Clone, Debug)] -pub enum APIVersion { - /// Version 0.11.0 of the backend API. - V0_11_0, -} - -#[async_trait] -impl FromRequestParts for APIVersion -where - S: Send + Sync, -{ - type Rejection = AxumResponse; - - async fn from_request_parts(parts: &mut Parts, _: &S) -> Result { - let parameters: Path> = - parts.extract().await.map_err(IntoResponse::into_response)?; - - let version = parameters - .get("version") - .ok_or_else(|| (StatusCode::NOT_FOUND, "version not specified").into_response())?; - - match version.as_str() { - "v0110" | "v1" => Ok(APIVersion::V0_11_0), - _ => Err((StatusCode::NOT_FOUND, "unknown version specified").into_response()), - } - } -} - /// An API response object. /// /// This is the object returned by a certain API endpoint. diff --git a/api-backend/hartex-backend-routes/src/uptime.rs b/api-backend/hartex-backend-routes/src/uptime.rs index 3ff93b76f..aa76b63b2 100644 --- a/api-backend/hartex-backend-routes/src/uptime.rs +++ b/api-backend/hartex-backend-routes/src/uptime.rs @@ -35,27 +35,23 @@ use bb8_postgres::PostgresConnectionManager; use hartex_backend_models::uptime::UptimeQuery; use hartex_backend_models::uptime::UptimeResponse; use hartex_backend_models::uptime::UptimeUpdate; -use hartex_backend_models::APIVersion; use hartex_backend_models::Response; use hartex_database_queries::api_backend::queries::start_timestamp_select_by_component::select_start_timestamp_by_component; use hartex_database_queries::api_backend::queries::start_timestamp_upsert::start_timestamp_upsert; use hartex_log::log; use time::OffsetDateTime; -/// # `GET /stats/uptime` -/// -/// Obtain the uptime of a certain component. +/// Get component uptime #[allow(clippy::cast_sign_loss)] #[allow(clippy::missing_panics_doc)] // this function cannot panic #[allow(clippy::module_name_repetitions)] #[utoipa::path( get, - path = "/stats/uptime", + path = "/api/v1/stats/uptime", params(UptimeQuery), responses((status = 200, description = "Uptime retrieved successfully", body = UptimeResponse)) )] pub async fn get_uptime( - _: APIVersion, State(pool): State>>, Query(query): Query, ) -> (StatusCode, Json>) { @@ -104,7 +100,6 @@ pub async fn get_uptime( #[allow(clippy::missing_panics_doc)] // this function cannot panic #[allow(clippy::module_name_repetitions)] pub async fn patch_uptime( - _: APIVersion, State(pool): State>>, Json(query): Json, ) -> (StatusCode, Json>) { From db48fefde3a9ac74d4f23125bd7c4f9e5f94c866 Mon Sep 17 00:00:00 2001 From: HTGAzureX1212 <39023054+HTGAzureX1212@users.noreply.github.com> Date: Sat, 2 Nov 2024 22:19:13 +0800 Subject: [PATCH 7/7] rename to extractors for future usage --- api-backend/Cargo.lock | 2 +- api-backend/Cargo.toml | 2 +- .../Cargo.toml | 4 ++-- .../src/lib.rs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename api-backend/{hartex-backend-layers => hartex-backend-extractors}/Cargo.toml (82%) rename api-backend/{hartex-backend-layers => hartex-backend-extractors}/src/lib.rs (89%) diff --git a/api-backend/Cargo.lock b/api-backend/Cargo.lock index 42f2368fd..b1121d786 100644 --- a/api-backend/Cargo.lock +++ b/api-backend/Cargo.lock @@ -724,7 +724,7 @@ dependencies = [ ] [[package]] -name = "hartex_backend_layers" +name = "hartex_backend_extractors" version = "0.13.0" [[package]] diff --git a/api-backend/Cargo.toml b/api-backend/Cargo.toml index dca2ebb8d..b2ed39034 100644 --- a/api-backend/Cargo.toml +++ b/api-backend/Cargo.toml @@ -1,7 +1,7 @@ [workspace] members = [ "hartex-backend-driver", - "hartex-backend-layers", + "hartex-backend-extractors", "hartex-backend-models", "hartex-backend-routes", ] diff --git a/api-backend/hartex-backend-layers/Cargo.toml b/api-backend/hartex-backend-extractors/Cargo.toml similarity index 82% rename from api-backend/hartex-backend-layers/Cargo.toml rename to api-backend/hartex-backend-extractors/Cargo.toml index 2f0edaf95..19c979c5f 100644 --- a/api-backend/hartex-backend-layers/Cargo.toml +++ b/api-backend/hartex-backend-extractors/Cargo.toml @@ -1,9 +1,9 @@ [package] -name = "hartex_backend_layers" +name = "hartex_backend_extractors" version = "0.13.0" edition = "2021" description = """ -Backend middleware +Backend extractors """ license = "AGPL-3.0-or-later" rust-version = "1.83.0" diff --git a/api-backend/hartex-backend-layers/src/lib.rs b/api-backend/hartex-backend-extractors/src/lib.rs similarity index 89% rename from api-backend/hartex-backend-layers/src/lib.rs rename to api-backend/hartex-backend-extractors/src/lib.rs index 3357b7cd5..0d9dfa73a 100644 --- a/api-backend/hartex-backend-layers/src/lib.rs +++ b/api-backend/hartex-backend-extractors/src/lib.rs @@ -20,9 +20,9 @@ * with HarTex. If not, see . */ -//! # Backend Layers +//! # Backend Extractors //! -//! This crate defines certain middleware layers for use with the Axum HTTP server. +//! This crate defines certain extractors for use with the Axum HTTP server. #![deny(clippy::pedantic)] #![deny(unsafe_code)]