global: snapshot

This commit is contained in:
nym21
2026-01-16 23:49:49 +01:00
parent 3b00a92fa4
commit 6bb1a2a311
34 changed files with 2600 additions and 5071 deletions

View File

@@ -6,11 +6,11 @@ use axum::{
http::{HeaderMap, StatusCode, Uri},
response::{IntoResponse, Response},
};
use brk_error::Result;
use brk_types::{Format, MetricSelection, Output};
use quick_cache::sync::GuardResult;
use crate::{
Result,
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
extended::HeaderMapExtended,
};
@@ -18,22 +18,10 @@ use crate::{
use super::AppState;
pub async fn handler(
uri: Uri,
headers: HeaderMap,
query: Query<MetricSelection>,
State(state): State<AppState>,
) -> Response {
match req_to_response_res(uri, headers, query, state).await {
Ok(response) => response,
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
}
}
async fn req_to_response_res(
uri: Uri,
headers: HeaderMap,
Query(params): Query<MetricSelection>,
AppState { query, cache, .. }: AppState,
State(AppState { query, cache, .. }): State<AppState>,
) -> Result<Response> {
// Phase 1: Search and resolve metadata (cheap)
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;

View File

@@ -6,11 +6,11 @@ use axum::{
http::{HeaderMap, StatusCode, Uri},
response::{IntoResponse, Response},
};
use brk_error::Result;
use brk_types::{Format, MetricSelection, Output};
use quick_cache::sync::GuardResult;
use crate::{
Result,
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
extended::HeaderMapExtended,
};
@@ -18,22 +18,10 @@ use crate::{
use super::AppState;
pub async fn handler(
uri: Uri,
headers: HeaderMap,
query: Query<MetricSelection>,
State(state): State<AppState>,
) -> Response {
match req_to_response_res(uri, headers, query, state).await {
Ok(response) => response,
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
}
}
async fn req_to_response_res(
uri: Uri,
headers: HeaderMap,
Query(params): Query<MetricSelection>,
AppState { query, cache, .. }: AppState,
State(AppState { query, cache, .. }): State<AppState>,
) -> Result<Response> {
// Phase 1: Search and resolve metadata (cheap)
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;

View File

@@ -6,11 +6,11 @@ use axum::{
http::{HeaderMap, StatusCode, Uri},
response::{IntoResponse, Response},
};
use brk_error::Result;
use brk_types::{Format, MetricSelection, OutputLegacy};
use quick_cache::sync::GuardResult;
use crate::{
Result,
api::metrics::{CACHE_CONTROL, MAX_WEIGHT},
extended::HeaderMapExtended,
};
@@ -18,22 +18,10 @@ use crate::{
use super::AppState;
pub async fn handler(
uri: Uri,
headers: HeaderMap,
query: Query<MetricSelection>,
State(state): State<AppState>,
) -> Response {
match req_to_response_res(uri, headers, query, state).await {
Ok(response) => response,
Err(error) => (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response(),
}
}
async fn req_to_response_res(
uri: Uri,
headers: HeaderMap,
Query(params): Query<MetricSelection>,
AppState { query, cache, .. }: AppState,
State(AppState { query, cache, .. }): State<AppState>,
) -> Result<Response> {
// Phase 1: Search and resolve metadata (cheap)
let resolved = query.run(move |q| q.resolve(params, MAX_WEIGHT)).await?;

View File

@@ -170,6 +170,7 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
state,
)
.await
.into_response()
},
|op| op
.id("get_metric")
@@ -188,7 +189,9 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
.api_route(
"/api/metrics/bulk",
get_with(
bulk::handler,
|uri, headers, query, state| async move {
bulk::handler(uri, headers, query, state).await.into_response()
},
|op| op
.id("get_metrics")
.metrics_tag()
@@ -225,7 +228,9 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
Metrics::from(split.collect::<Vec<_>>().join(separator)),
range,
));
legacy::handler(uri, headers, Query(params), state).await
legacy::handler(uri, headers, Query(params), state)
.await
.into_response()
},
|op| op
.metrics_tag()
@@ -250,7 +255,9 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
state: State<AppState>|
-> Response {
let params: MetricSelection = params.into();
legacy::handler(uri, headers, Query(params), state).await
legacy::handler(uri, headers, Query(params), state)
.await
.into_response()
},
|op| op
.metrics_tag()

View File

@@ -48,7 +48,7 @@ impl ApiRoutes for ApiRouter<AppState> {
.add_server_routes()
.route("/api/server", get(Redirect::temporary("/api#tag/server")))
.api_route(
"/api.json",
"/openapi.json",
get_with(
async |headers: HeaderMap,
Extension(api): Extension<Arc<OpenApi>>|
@@ -62,7 +62,7 @@ impl ApiRoutes for ApiRouter<AppState> {
),
)
.api_route(
"/api.trimmed.json",
"/api.json",
get_with(
async |headers: HeaderMap,
Extension(api_trimmed): Extension<Arc<String>>|
@@ -72,12 +72,13 @@ impl ApiRoutes for ApiRouter<AppState> {
Response::static_json(&headers, &value)
},
|op| {
op.id("get_openapi_trimmed")
op.id("get_api")
.server_tag()
.summary("Trimmed OpenAPI specification")
.summary("Compact OpenAPI specification")
.description(
"Compact OpenAPI specification optimized for LLM consumption. \
Removes redundant fields while preserving essential API information.",
Removes redundant fields while preserving essential API information. \
Full spec available at `/openapi.json`.",
)
.ok_response::<serde_json::Value>()
},

View File

@@ -29,7 +29,7 @@ pub fn create_openapi() -> OpenApi {
- **Metrics**: Thousands of time-series metrics across multiple indexes (date, block height, etc.)
- **[Mempool.space](https://mempool.space/docs/api/rest) compatible** (WIP): Most non-metrics endpoints follow the mempool.space API format
- **Multiple formats**: JSON and CSV output
- **LLM-optimized**: Compact OpenAPI spec at [`/api.trimmed.json`](/api.trimmed.json) for AI tools
- **LLM-optimized**: Compact OpenAPI spec at [`/api.json`](/api.json) for AI tools (full spec at [`/openapi.json`](/openapi.json))
### Client Libraries

View File

@@ -18,7 +18,7 @@
<script>
Scalar.createApiReference("#app", {
url: "/api.json",
url: "/openapi.json",
hideClientButton: true,
telemetry: false,
// showToolbar: "never",