From f457d9ce7be5deb3fb935c25e98d3267aa4333a7 Mon Sep 17 00:00:00 2001 From: damocles Date: Sun, 2 Aug 2026 21:09:28 +0200 Subject: [PATCH] hive-c0re: drop utoipa-swagger-ui, serve openapi.json directly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Swagger UI itself is nginx-hosted now (iris's 86a39c4c), so c0re carrying its own vendored copy via utoipa-swagger-ui was a straight duplicate — dropped the dependency (root Cargo.toml + hive-c0re's), swapped the SwaggerUi::new(...).url(...) mount for a plain /api/openapi.json GET route serving the same OpenApi doc as JSON. Verified: cargo build/clippy/test -p hive-c0re clean, Cargo.lock dropped utoipa-swagger-ui + utoipa-swagger-ui-vendored with no other changes, nix fmt clean. --- Cargo.lock | 114 --------------------------------- Cargo.toml | 5 -- hive-c0re/Cargo.toml | 1 - hive-c0re/src/dashboard/mod.rs | 20 ++++-- 4 files changed, 16 insertions(+), 124 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8ac44a4c..399f5765 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,15 +135,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" -dependencies = [ - "derive_arbitrary", -] - [[package]] name = "archery" version = "1.2.2" @@ -990,17 +981,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.119", -] - [[package]] name = "derive_more" version = "1.0.0" @@ -1276,7 +1256,6 @@ checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" dependencies = [ "crc32fast", "miniz_oxide", - "zlib-rs", ] [[package]] @@ -1681,7 +1660,6 @@ dependencies = [ "url", "utoipa", "utoipa-axum", - "utoipa-swagger-ui", ] [[package]] @@ -3924,41 +3902,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "rust-embed" -version = "8.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e7760e252aaba7b09f4be00e36476cf585bdb68a53552ac954cdf504ab4bc9" -dependencies = [ - "rust-embed-impl", - "rust-embed-utils", - "walkdir", -] - -[[package]] -name = "rust-embed-impl" -version = "8.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bcfc4d6f53af43755f7a723e4b6b8794fcce052a178dd8c6c1dadc5f5343097" -dependencies = [ - "mime_guess", - "proc-macro2", - "quote", - "rust-embed-utils", - "syn 2.0.119", - "walkdir", -] - -[[package]] -name = "rust-embed-utils" -version = "8.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ffa149f6aa81b58a5b3011d01a857c4ed12c7a732d2c51947a4c7c692185f0" -dependencies = [ - "sha2 0.11.0", - "walkdir", -] - [[package]] name = "rustc-hash" version = "2.1.3" @@ -5078,31 +5021,6 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "utoipa-swagger-ui" -version = "9.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d047458f1b5b65237c2f6dc6db136945667f40a7668627b3490b9513a3d43a55" -dependencies = [ - "axum", - "base64", - "mime_guess", - "regex", - "rust-embed", - "serde", - "serde_json", - "url", - "utoipa", - "utoipa-swagger-ui-vendored", - "zip", -] - -[[package]] -name = "utoipa-swagger-ui-vendored" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2eebbbfe4093922c2b6734d7c679ebfebd704a0d7e56dfcb0d05818ce28977d" - [[package]] name = "uuid" version = "1.24.0" @@ -5745,40 +5663,8 @@ dependencies = [ "syn 2.0.119", ] -[[package]] -name = "zip" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308" -dependencies = [ - "arbitrary", - "crc32fast", - "flate2", - "indexmap", - "memchr", - "zopfli", -] - -[[package]] -name = "zlib-rs" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b142a20ec14a91d5bc708c1dc21b080c550113d8aa77afa29635673a65dd02c5" - [[package]] name = "zmij" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" - -[[package]] -name = "zopfli" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f05cd8797d63865425ff89b5c4a48804f35ba0ce8d125800027ad6017d2b5249" -dependencies = [ - "bumpalo", - "crc32fast", - "log", - "simd-adler32", -] diff --git a/Cargo.toml b/Cargo.toml index eb79b132..56a33612 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -116,8 +116,3 @@ hmac = "0.13" sha2 = "0.11" utoipa = { version = "5", features = ["axum_extras"] } utoipa-axum = "0.2" -# "vendored" bundles a pinned Swagger UI dist via utoipa-swagger-ui-vendored -# instead of the crate's default curl-download build script — required in -# the nix sandbox, which has no network at build time outside the -# Cargo.lock-pinned dependency fetch. -utoipa-swagger-ui = { version = "9", features = ["axum", "vendored"] } diff --git a/hive-c0re/Cargo.toml b/hive-c0re/Cargo.toml index 98a6e459..a4dae331 100644 --- a/hive-c0re/Cargo.toml +++ b/hive-c0re/Cargo.toml @@ -53,7 +53,6 @@ tracing-subscriber.workspace = true problem_details = { version = "0.9.0", features = ["axum"] } utoipa.workspace = true utoipa-axum.workspace = true -utoipa-swagger-ui.workspace = true [dev-dependencies] tempfile = "3" diff --git a/hive-c0re/src/dashboard/mod.rs b/hive-c0re/src/dashboard/mod.rs index 9e2a12e6..463ce242 100644 --- a/hive-c0re/src/dashboard/mod.rs +++ b/hive-c0re/src/dashboard/mod.rs @@ -7,18 +7,23 @@ use std::sync::Arc; use anyhow::{Context, Result}; use axum::{ + Json, http::StatusCode, response::{IntoResponse, Response}, + routing::get, }; use utoipa::OpenApi; use utoipa_axum::{router::OpenApiRouter, routes}; -use utoipa_swagger_ui::SwaggerUi; use crate::coordinator::Coordinator; use crate::lifecycle; -/// Root of the auto-generated `OpenAPI` spec (`/api/openapi.json`, browsable -/// at `/api/docs`) — see [`utoipa`]. Only routes carrying a +/// Root of the auto-generated `OpenAPI` spec, served raw at +/// `/api/openapi.json` — see [`utoipa`]. Swagger UI itself (browsable at +/// `/api/docs`) is nginx-hosted straight from the nix store now (see +/// `nix/host-modules/hive-gateway/vhosts.nix`'s `swaggerUiLocations`); +/// c0re only needs to serve the JSON this route generates, not the whole +/// vendored UI. Only routes carrying a /// `#[utoipa::path(...)]` annotation show up; the rest of the (much /// larger) route table below is undocumented for now. Deliberately /// incremental: an unannotated route just doesn't appear in the spec, @@ -206,8 +211,15 @@ pub async fn serve( .routes(routes!(state_snapshot::dashboard_stream)) .routes(routes!(state_snapshot::dashboard_history)) .split_for_parts(); + // Just the JSON, not the UI — Swagger UI itself is nginx-hosted from + // the nix store (see the module doc comment above `ApiDoc`). `api` + // is `Clone`; each request gets its own owned copy for `Json` to + // serialize. let app = router - .merge(SwaggerUi::new("/api/docs").url("/api/openapi.json", api)) + .route( + "/api/openapi.json", + get(move || async move { Json(api.clone()) }), + ) .with_state(AppState { coord, webhook_secret,