mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-09 01:58:14 -07:00
mempool: general improvements
This commit is contained in:
@@ -2,8 +2,6 @@ use aide::axum::{ApiRouter, routing::get_with};
|
||||
use axum::{
|
||||
extract::{Path, Query, State},
|
||||
http::{HeaderMap, Uri},
|
||||
response::Redirect,
|
||||
routing::get,
|
||||
};
|
||||
use brk_types::{AddrStats, AddrValidation, Transaction, Txid, Utxo, Version};
|
||||
|
||||
@@ -19,10 +17,7 @@ pub trait AddrRoutes {
|
||||
|
||||
impl AddrRoutes for ApiRouter<AppState> {
|
||||
fn add_addr_routes(self) -> Self {
|
||||
self
|
||||
.route("/api/address", get(Redirect::temporary("/api/addresses")))
|
||||
.route("/api/addresses", get(Redirect::temporary("/api#tag/addresses")))
|
||||
.api_route(
|
||||
self.api_route(
|
||||
"/api/address/{address}",
|
||||
get_with(async |
|
||||
uri: Uri,
|
||||
@@ -31,8 +26,8 @@ impl AddrRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let strategy = state.addr_cache(Version::ONE, &path.addr, false);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| q.addr(path.addr)).await
|
||||
let strategy = state.addr_strategy(Version::ONE, &path.addr, false);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| q.addr(path.addr)).await
|
||||
}, |op| op
|
||||
.id("get_address")
|
||||
.addrs_tag()
|
||||
@@ -54,8 +49,8 @@ impl AddrRoutes for ApiRouter<AppState> {
|
||||
Query(params): Query<AddrTxidsParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let strategy = state.addr_cache(Version::ONE, &path.addr, false);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| q.addr_txs(path.addr, params.after_txid, 50)).await
|
||||
let strategy = state.addr_strategy(Version::ONE, &path.addr, false);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| q.addr_txs(path.addr, params.after_txid, 50)).await
|
||||
}, |op| op
|
||||
.id("get_address_txs")
|
||||
.addrs_tag()
|
||||
@@ -77,8 +72,8 @@ impl AddrRoutes for ApiRouter<AppState> {
|
||||
Query(params): Query<AddrTxidsParam>,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let strategy = state.addr_cache(Version::ONE, &path.addr, true);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| q.addr_txs(path.addr, params.after_txid, 25)).await
|
||||
let strategy = state.addr_strategy(Version::ONE, &path.addr, true);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| q.addr_txs(path.addr, params.after_txid, 25)).await
|
||||
}, |op| op
|
||||
.id("get_address_confirmed_txs")
|
||||
.addrs_tag()
|
||||
@@ -101,7 +96,7 @@ impl AddrRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let hash = state.sync(|q| q.addr_mempool_hash(&path.addr));
|
||||
state.cached_json(&headers, CacheStrategy::MempoolHash(hash), &uri, move |q| q.addr_mempool_txids(path.addr)).await
|
||||
state.respond_json(&headers, CacheStrategy::MempoolHash(hash), &uri, move |q| q.addr_mempool_txids(path.addr)).await
|
||||
}, |op| op
|
||||
.id("get_address_mempool_txs")
|
||||
.addrs_tag()
|
||||
@@ -123,8 +118,8 @@ impl AddrRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let strategy = state.addr_cache(Version::ONE, &path.addr, false);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| q.addr_utxos(path.addr)).await
|
||||
let strategy = state.addr_strategy(Version::ONE, &path.addr, false);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| q.addr_utxos(path.addr)).await
|
||||
}, |op| op
|
||||
.id("get_address_utxos")
|
||||
.addrs_tag()
|
||||
@@ -146,7 +141,7 @@ impl AddrRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, move |_q| Ok(AddrValidation::from_addr(&path.addr))).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, move |_q| Ok(AddrValidation::from_addr(&path.addr))).await
|
||||
}, |op| op
|
||||
.id("validate_address")
|
||||
.addrs_tag()
|
||||
|
||||
@@ -29,8 +29,8 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
let strategy = state.block_cache(Version::ONE, &path.hash);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| q.block(&path.hash)).await
|
||||
let strategy = state.block_strategy(Version::ONE, &path.hash);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| q.block(&path.hash)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block")
|
||||
@@ -51,8 +51,8 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/block/{hash}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<BlockHashParam>, _: Empty, State(state): State<AppState>| {
|
||||
let strategy = state.block_cache(Version::ONE, &path.hash);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| {
|
||||
let strategy = state.block_strategy(Version::ONE, &path.hash);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| {
|
||||
let height = q.height_by_hash(&path.hash)?;
|
||||
q.block_by_height_v1(height)
|
||||
}).await
|
||||
@@ -74,8 +74,8 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/block/{hash}/header",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<BlockHashParam>, _: Empty, State(state): State<AppState>| {
|
||||
let strategy = state.block_cache(Version::ONE, &path.hash);
|
||||
state.cached_text(&headers, strategy, &uri, move |q| q.block_header_hex(&path.hash)).await
|
||||
let strategy = state.block_strategy(Version::ONE, &path.hash);
|
||||
state.respond_text(&headers, strategy, &uri, move |q| q.block_header_hex(&path.hash)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_header")
|
||||
@@ -97,7 +97,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<HeightParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
state.cached_text(&headers, state.height_cache(Version::ONE, path.height), &uri, move |q| q.block_hash_by_height(path.height).map(|h| h.to_string())).await
|
||||
state.respond_text(&headers, state.height_strategy(Version::ONE, path.height), &uri, move |q| q.block_hash_by_height(path.height).map(|h| h.to_string())).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_by_height")
|
||||
@@ -121,7 +121,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<TimestampParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.timestamp_cache(Version::ONE, path.timestamp), &uri, move |q| q.block_by_timestamp(path.timestamp)).await
|
||||
state.respond_json(&headers, state.timestamp_strategy(Version::ONE, path.timestamp), &uri, move |q| q.block_by_timestamp(path.timestamp)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_by_timestamp")
|
||||
@@ -143,8 +143,8 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
let strategy = state.block_cache(Version::ONE, &path.hash);
|
||||
state.cached_bytes(&headers, strategy, &uri, move |q| q.block_raw(&path.hash)).await
|
||||
let strategy = state.block_strategy(Version::ONE, &path.hash);
|
||||
state.respond_bytes(&headers, strategy, &uri, move |q| q.block_raw(&path.hash)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_raw")
|
||||
@@ -168,7 +168,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.block_status_cache(Version::ONE, &path.hash), &uri, move |q| q.block_status(&path.hash)).await
|
||||
state.respond_json(&headers, state.block_status_strategy(Version::ONE, &path.hash), &uri, move |q| q.block_status(&path.hash)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_status")
|
||||
@@ -189,7 +189,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/blocks/tip/height",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_text(&headers, CacheStrategy::Tip, &uri, |q| Ok(q.indexed_height().to_string())).await
|
||||
state.respond_text(&headers, CacheStrategy::Tip, &uri, |q| Ok(q.indexed_height().to_string())).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_tip_height")
|
||||
@@ -206,7 +206,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
"/api/blocks/tip/hash",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_text(&headers, CacheStrategy::Tip, &uri, |q| Ok(q.tip_blockhash().to_string())).await
|
||||
state.respond_text(&headers, CacheStrategy::Tip, &uri, |q| Ok(q.tip_blockhash().to_string())).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_tip_hash")
|
||||
@@ -226,8 +226,8 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<BlockHashTxIndex>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
let strategy = state.block_cache(Version::ONE, &path.hash);
|
||||
state.cached_text(&headers, strategy, &uri, move |q| q.block_txid_at_index(&path.hash, path.index).map(|t| t.to_string())).await
|
||||
let strategy = state.block_strategy(Version::ONE, &path.hash);
|
||||
state.respond_text(&headers, strategy, &uri, move |q| q.block_txid_at_index(&path.hash, path.index).map(|t| t.to_string())).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_txid")
|
||||
@@ -251,8 +251,8 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
let strategy = state.block_cache(Version::ONE, &path.hash);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| q.block_txids(&path.hash)).await
|
||||
let strategy = state.block_strategy(Version::ONE, &path.hash);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| q.block_txids(&path.hash)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_txids")
|
||||
@@ -276,8 +276,8 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<BlockHashParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
let strategy = state.block_cache(Version::ONE, &path.hash);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| q.block_txs(&path.hash, TxIndex::default())).await
|
||||
let strategy = state.block_strategy(Version::ONE, &path.hash);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| q.block_txs(&path.hash, TxIndex::default())).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_txs")
|
||||
@@ -302,8 +302,8 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<BlockHashStartIndex>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
let strategy = state.block_cache(Version::ONE, &path.hash);
|
||||
state.cached_json(&headers, strategy, &uri, move |q| q.block_txs(&path.hash, path.start_index)).await
|
||||
let strategy = state.block_strategy(Version::ONE, &path.hash);
|
||||
state.respond_json(&headers, strategy, &uri, move |q| q.block_txs(&path.hash, path.start_index)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_txs_from_index")
|
||||
@@ -326,7 +326,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.blocks(None))
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.blocks(None))
|
||||
.await
|
||||
},
|
||||
|op| {
|
||||
@@ -347,7 +347,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<HeightParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.height_cache(Version::ONE, path.height), &uri, move |q| q.blocks(Some(path.height))).await
|
||||
state.respond_json(&headers, state.height_strategy(Version::ONE, path.height), &uri, move |q| q.blocks(Some(path.height))).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_blocks_from_height")
|
||||
@@ -368,7 +368,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.blocks_v1(None))
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.blocks_v1(None))
|
||||
.await
|
||||
},
|
||||
|op| {
|
||||
@@ -389,7 +389,7 @@ impl BlockRoutes for ApiRouter<AppState> {
|
||||
headers: HeaderMap,
|
||||
Path(path): Path<HeightParam>,
|
||||
_: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.height_cache(Version::ONE, path.height), &uri, move |q| q.blocks_v1(Some(path.height))).await
|
||||
state.respond_json(&headers, state.height_strategy(Version::ONE, path.height), &uri, move |q| q.blocks_v1(Some(path.height))).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_blocks_v1_from_height")
|
||||
|
||||
@@ -18,7 +18,7 @@ impl FeesRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, state.mempool_cache(), &uri, |q| {
|
||||
.respond_json(&headers, state.mempool_strategy(), &uri, |q| {
|
||||
q.mempool_blocks()
|
||||
})
|
||||
.await
|
||||
@@ -39,7 +39,7 @@ impl FeesRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, state.mempool_cache(), &uri, |q| {
|
||||
.respond_json(&headers, state.mempool_strategy(), &uri, |q| {
|
||||
q.recommended_fees()
|
||||
})
|
||||
.await
|
||||
@@ -60,7 +60,7 @@ impl FeesRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, state.mempool_cache(), &uri, |q| {
|
||||
.respond_json(&headers, state.mempool_strategy(), &uri, |q| {
|
||||
q.recommended_fees()
|
||||
})
|
||||
.await
|
||||
|
||||
@@ -22,7 +22,7 @@ impl GeneralRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, |q| {
|
||||
q.difficulty_adjustment()
|
||||
})
|
||||
.await
|
||||
@@ -43,7 +43,7 @@ impl GeneralRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, state.mempool_cache(), &uri, |q| {
|
||||
.respond_json(&headers, state.mempool_strategy(), &uri, |q| {
|
||||
Ok(Prices {
|
||||
time: Timestamp::now(),
|
||||
usd: q.live_price()?,
|
||||
@@ -71,10 +71,10 @@ impl GeneralRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>| {
|
||||
let strategy = params
|
||||
.timestamp
|
||||
.map(|ts| state.timestamp_cache(Version::ONE, ts))
|
||||
.map(|ts| state.timestamp_strategy(Version::ONE, ts))
|
||||
.unwrap_or(CacheStrategy::Tip);
|
||||
state
|
||||
.cached_json(&headers, strategy, &uri, move |q| {
|
||||
.respond_json(&headers, strategy, &uri, move |q| {
|
||||
q.historical_price(params.timestamp)
|
||||
})
|
||||
.await
|
||||
|
||||
@@ -18,7 +18,7 @@ impl MempoolRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, state.mempool_cache(), &uri, |q| q.mempool_info())
|
||||
.respond_json(&headers, state.mempool_strategy(), &uri, |q| q.mempool_info())
|
||||
.await
|
||||
},
|
||||
|op| {
|
||||
@@ -37,7 +37,7 @@ impl MempoolRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, state.mempool_cache(), &uri, |q| q.mempool_txids())
|
||||
.respond_json(&headers, state.mempool_strategy(), &uri, |q| q.mempool_txids())
|
||||
.await
|
||||
},
|
||||
|op| {
|
||||
@@ -56,7 +56,7 @@ impl MempoolRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, state.mempool_cache(), &uri, |q| q.mempool_recent())
|
||||
.respond_json(&headers, state.mempool_strategy(), &uri, |q| q.mempool_recent())
|
||||
.await
|
||||
},
|
||||
|op| {
|
||||
@@ -75,7 +75,7 @@ impl MempoolRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, state.mempool_cache(), &uri, |q| q.live_price())
|
||||
.respond_json(&headers, state.mempool_strategy(), &uri, |q| q.live_price())
|
||||
.await
|
||||
},
|
||||
|op| {
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use aide::axum::{ApiRouter, routing::get_with};
|
||||
use axum::{
|
||||
Extension,
|
||||
extract::{Path, Query, State},
|
||||
http::{HeaderMap, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
@@ -47,7 +44,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
"/api/metrics",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.series_catalog().clone())).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.series_catalog().clone())).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_metrics_tree_deprecated")
|
||||
@@ -71,7 +68,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.series_count())).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.series_count())).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_metrics_count_deprecated")
|
||||
@@ -95,7 +92,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.indexes().to_vec())).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.indexes().to_vec())).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_indexes_deprecated")
|
||||
@@ -119,7 +116,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Query(pagination): Query<Pagination>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, move |q| Ok(q.series_list(pagination))).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, move |q| Ok(q.series_list(pagination))).await
|
||||
},
|
||||
|op| op
|
||||
.id("list_metrics_deprecated")
|
||||
@@ -143,7 +140,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Query(query): Query<SearchQuery>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, move |q| Ok(q.search_series(&query))).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, move |q| Ok(q.search_series(&query))).await
|
||||
},
|
||||
|op| op
|
||||
.id("search_metrics_deprecated")
|
||||
@@ -162,8 +159,8 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/metrics/bulk",
|
||||
get_with(
|
||||
|uri: Uri, headers: HeaderMap, addr: Extension<SocketAddr>, query: Query<SeriesSelection>, state: State<AppState>| async move {
|
||||
series_legacy::handler(uri, headers, addr, query, state)
|
||||
|uri: Uri, headers: HeaderMap, query: Query<SeriesSelection>, state: State<AppState>| async move {
|
||||
series_legacy::handler(uri, headers, query, state)
|
||||
.await
|
||||
.into_response()
|
||||
},
|
||||
@@ -192,7 +189,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Path(path): Path<LegacySeriesParam>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, move |q| {
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, move |q| {
|
||||
q.series_info(&path.metric).ok_or_else(|| q.series_not_found_error(&path.metric))
|
||||
}).await
|
||||
},
|
||||
@@ -216,13 +213,12 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri,
|
||||
headers: HeaderMap,
|
||||
addr: Extension<SocketAddr>,
|
||||
state: State<AppState>,
|
||||
Path(path): Path<LegacySeriesWithIndex>,
|
||||
Query(range): Query<DataRangeFormat>|
|
||||
-> Response {
|
||||
let params = SeriesSelection::from((path.index, path.metric, range));
|
||||
series_legacy::handler(uri, headers, addr, Query(params), state)
|
||||
series_legacy::handler(uri, headers, Query(params), state)
|
||||
.await
|
||||
.into_response()
|
||||
},
|
||||
@@ -246,13 +242,12 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri,
|
||||
headers: HeaderMap,
|
||||
addr: Extension<SocketAddr>,
|
||||
state: State<AppState>,
|
||||
Path(path): Path<LegacySeriesWithIndex>,
|
||||
Query(range): Query<DataRangeFormat>|
|
||||
-> Response {
|
||||
let params = SeriesSelection::from((path.index, path.metric, range));
|
||||
series_legacy::handler(uri, headers, addr, Query(params), state)
|
||||
series_legacy::handler(uri, headers, Query(params), state)
|
||||
.await
|
||||
.into_response()
|
||||
},
|
||||
@@ -280,7 +275,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Path(path): Path<LegacySeriesWithIndex>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.latest(&path.metric, path.index)
|
||||
})
|
||||
.await
|
||||
@@ -307,7 +302,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Path(path): Path<LegacySeriesWithIndex>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.len(&path.metric, path.index)
|
||||
})
|
||||
.await
|
||||
@@ -334,7 +329,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Path(path): Path<LegacySeriesWithIndex>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.version(&path.metric, path.index)
|
||||
})
|
||||
.await
|
||||
@@ -358,7 +353,6 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri,
|
||||
headers: HeaderMap,
|
||||
addr: Extension<SocketAddr>,
|
||||
Path(variant): Path<String>,
|
||||
Query(range): Query<DataRangeFormat>,
|
||||
state: State<AppState>|
|
||||
@@ -379,7 +373,7 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
SeriesList::from(split.collect::<Vec<_>>().join(separator)),
|
||||
range,
|
||||
));
|
||||
series_legacy::handler(uri, headers, addr, Query(params), state)
|
||||
series_legacy::handler(uri, headers, Query(params), state)
|
||||
.await
|
||||
.into_response()
|
||||
},
|
||||
@@ -402,12 +396,11 @@ impl ApiMetricsLegacyRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri,
|
||||
headers: HeaderMap,
|
||||
addr: Extension<SocketAddr>,
|
||||
Query(params): Query<SeriesSelectionLegacy>,
|
||||
state: State<AppState>|
|
||||
-> Response {
|
||||
let params: SeriesSelection = params.into();
|
||||
series_legacy::handler(uri, headers, addr, Query(params), state)
|
||||
series_legacy::handler(uri, headers, Query(params), state)
|
||||
.await
|
||||
.into_response()
|
||||
},
|
||||
|
||||
@@ -2,8 +2,6 @@ use aide::axum::{ApiRouter, routing::get_with};
|
||||
use axum::{
|
||||
extract::{Path, State},
|
||||
http::{HeaderMap, Uri},
|
||||
response::Redirect,
|
||||
routing::get,
|
||||
};
|
||||
use brk_types::{
|
||||
BlockFeeRatesEntry, BlockFeesEntry, BlockInfoV1, BlockRewardsEntry, BlockSizesWeights,
|
||||
@@ -23,16 +21,12 @@ pub trait MiningRoutes {
|
||||
|
||||
impl MiningRoutes for ApiRouter<AppState> {
|
||||
fn add_mining_routes(self) -> Self {
|
||||
self.route(
|
||||
"/api/v1/mining",
|
||||
get(Redirect::temporary("/api#tag/mining")),
|
||||
)
|
||||
.api_route(
|
||||
self.api_route(
|
||||
"/api/v1/mining/pools",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
// Pool list is compiled-in, only changes on deploy
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.all_pools())).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.all_pools())).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_pools")
|
||||
@@ -49,7 +43,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/pools/{time_period}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<TimePeriodParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.mining_pools(path.time_period)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.mining_pools(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_pool_stats")
|
||||
@@ -67,7 +61,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/pool/{slug}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<PoolSlugParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.pool_detail(path.slug)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.pool_detail(path.slug)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_pool")
|
||||
@@ -85,7 +79,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/hashrate/pools",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, |q| q.pools_hashrate(None)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, |q| q.pools_hashrate(None)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_pools_hashrate")
|
||||
@@ -102,7 +96,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/hashrate/pools/{time_period}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<TimePeriodParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.pools_hashrate(Some(path.time_period))).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.pools_hashrate(Some(path.time_period))).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_pools_hashrate_by_period")
|
||||
@@ -120,7 +114,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/pool/{slug}/hashrate",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<PoolSlugParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.pool_hashrate(path.slug)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.pool_hashrate(path.slug)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_pool_hashrate")
|
||||
@@ -138,7 +132,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/pool/{slug}/blocks",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<PoolSlugParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.pool_blocks(path.slug, None)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.pool_blocks(path.slug, None)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_pool_blocks")
|
||||
@@ -156,7 +150,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/pool/{slug}/blocks/{height}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(PoolSlugAndHeightParam {slug, height}): Path<PoolSlugAndHeightParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.height_cache(Version::ONE, height), &uri, move |q| q.pool_blocks(slug, Some(height))).await
|
||||
state.respond_json(&headers, state.height_strategy(Version::ONE, height), &uri, move |q| q.pool_blocks(slug, Some(height))).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_pool_blocks_from")
|
||||
@@ -174,7 +168,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/hashrate",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, |q| q.hashrate(None)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, |q| q.hashrate(None)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_hashrate")
|
||||
@@ -191,7 +185,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/hashrate/{time_period}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<TimePeriodParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.hashrate(Some(path.time_period))).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.hashrate(Some(path.time_period))).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_hashrate_by_period")
|
||||
@@ -209,7 +203,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/difficulty-adjustments",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, |q| q.difficulty_adjustments(None)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, |q| q.difficulty_adjustments(None)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_difficulty_adjustments")
|
||||
@@ -226,7 +220,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/difficulty-adjustments/{time_period}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<TimePeriodParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.difficulty_adjustments(Some(path.time_period))).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.difficulty_adjustments(Some(path.time_period))).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_difficulty_adjustments_by_period")
|
||||
@@ -244,7 +238,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/reward-stats/{block_count}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<BlockCountParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.reward_stats(path.block_count)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.reward_stats(path.block_count)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_reward_stats")
|
||||
@@ -262,7 +256,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/blocks/fees/{time_period}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<TimePeriodParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.block_fees(path.time_period)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.block_fees(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_fees")
|
||||
@@ -280,7 +274,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/blocks/rewards/{time_period}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<TimePeriodParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.block_rewards(path.time_period)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.block_rewards(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_rewards")
|
||||
@@ -298,7 +292,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/blocks/fee-rates/{time_period}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<TimePeriodParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.block_fee_rates(path.time_period)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.block_fee_rates(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_fee_rates")
|
||||
@@ -316,7 +310,7 @@ impl MiningRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/mining/blocks/sizes-weights/{time_period}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(path): Path<TimePeriodParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| q.block_sizes_weights(path.time_period)).await
|
||||
state.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| q.block_sizes_weights(path.time_period)).await
|
||||
},
|
||||
|op| {
|
||||
op.id("get_block_sizes_weights")
|
||||
|
||||
@@ -1,9 +1,4 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use aide::{
|
||||
axum::{ApiRouter, routing::get_with},
|
||||
openapi::OpenApi,
|
||||
};
|
||||
use aide::axum::{ApiRouter, routing::get_with};
|
||||
use axum::{
|
||||
Extension,
|
||||
http::HeaderMap,
|
||||
@@ -63,13 +58,14 @@ impl ApiRoutes for ApiRouter<AppState> {
|
||||
.add_fees_routes()
|
||||
.add_mempool_routes()
|
||||
.add_tx_routes()
|
||||
.route("/api/server", get(Redirect::temporary("/api#tag/server")))
|
||||
.api_route(
|
||||
"/openapi.json",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Extension(api): Extension<Arc<OpenApi>>|
|
||||
-> Response { Response::static_json(&headers, &*api) },
|
||||
Extension(api): Extension<OpenApiJson>|
|
||||
-> Response {
|
||||
Response::static_json_bytes(&headers, api.bytes())
|
||||
},
|
||||
|op| {
|
||||
op.id("get_openapi")
|
||||
.server_tag()
|
||||
@@ -82,9 +78,9 @@ impl ApiRoutes for ApiRouter<AppState> {
|
||||
"/api.json",
|
||||
get_with(
|
||||
async |headers: HeaderMap,
|
||||
Extension(api): Extension<Arc<ApiJson>>|
|
||||
Extension(api): Extension<ApiJson>|
|
||||
-> Response {
|
||||
Response::static_json(&headers, api.to_json())
|
||||
Response::static_json_bytes(&headers, api.bytes())
|
||||
},
|
||||
|op| {
|
||||
op.id("get_api")
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
use aide::openapi::OpenApi;
|
||||
use derive_more::Deref;
|
||||
use axum::body::Bytes;
|
||||
use serde_json::{Map, Value};
|
||||
|
||||
/// Compact OpenAPI spec optimized for LLM consumption.
|
||||
#[derive(Deref)]
|
||||
pub struct ApiJson(String);
|
||||
/// Pre-serialized at startup, served as raw bytes per request.
|
||||
#[derive(Clone)]
|
||||
pub struct ApiJson(Bytes);
|
||||
|
||||
impl ApiJson {
|
||||
pub fn new(openapi: &OpenApi) -> Self {
|
||||
let json = serde_json::to_string(openapi).unwrap();
|
||||
Self(compact_json(&json))
|
||||
Self(Bytes::from(compact_json(&json)))
|
||||
}
|
||||
|
||||
pub fn to_json(&self) -> serde_json::Value {
|
||||
serde_json::from_str(&self.0).unwrap()
|
||||
pub fn bytes(&self) -> Bytes {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
use aide::openapi::OpenApi;
|
||||
use axum::body::Bytes;
|
||||
|
||||
/// Full OpenAPI spec, pre-serialized at startup and served as raw bytes per request.
|
||||
#[derive(Clone)]
|
||||
pub struct OpenApiJson(Bytes);
|
||||
|
||||
impl OpenApiJson {
|
||||
pub fn new(openapi: &OpenApi) -> Self {
|
||||
Self(Bytes::from(serde_json::to_vec(openapi).unwrap()))
|
||||
}
|
||||
|
||||
pub fn bytes(&self) -> Bytes {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,10 @@
|
||||
//
|
||||
|
||||
mod compact;
|
||||
mod full;
|
||||
|
||||
pub use compact::ApiJson;
|
||||
pub use full::OpenApiJson;
|
||||
|
||||
use aide::openapi::{Contact, Info, License, OpenApi, Tag};
|
||||
|
||||
|
||||
@@ -4,11 +4,8 @@
|
||||
//! a formatted body (single + raw + bulk + the legacy module's deprecated
|
||||
//! handler in `series_legacy.rs`).
|
||||
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use aide::axum::{ApiRouter, routing::get_with};
|
||||
use axum::{
|
||||
Extension,
|
||||
body::Bytes,
|
||||
extract::{Path, Query, State},
|
||||
http::{HeaderMap, Uri},
|
||||
@@ -31,17 +28,16 @@ use crate::{
|
||||
/// Shared response pipeline for every series endpoint.
|
||||
///
|
||||
/// Resolves the query (which determines the cache key), then delegates to
|
||||
/// [`AppState::cached_with_params`] for the etag short-circuit, server-side
|
||||
/// [`AppState::respond_with_params`] for the etag short-circuit, server-side
|
||||
/// cache lookup, body formatting, and header assembly.
|
||||
pub(super) async fn serve(
|
||||
state: AppState,
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
addr: SocketAddr,
|
||||
params: SeriesSelection,
|
||||
to_bytes: impl FnOnce(&BrkQuery, ResolvedQuery) -> BrkResult<Bytes> + Send + 'static,
|
||||
) -> Result<Response> {
|
||||
let max_weight = state.max_weight_for(&addr);
|
||||
let max_weight = state.max_weight;
|
||||
let resolved = state.run(move |q| q.resolve(params, max_weight)).await?;
|
||||
|
||||
let format = resolved.format();
|
||||
@@ -54,7 +50,7 @@ pub(super) async fn serve(
|
||||
);
|
||||
|
||||
Ok(state
|
||||
.cached_with_params(
|
||||
.respond_with_params(
|
||||
&headers,
|
||||
&uri,
|
||||
cache_params,
|
||||
@@ -65,7 +61,7 @@ pub(super) async fn serve(
|
||||
}
|
||||
Format::JSON => h.insert_content_type_application_json(),
|
||||
},
|
||||
move |q, enc| Ok(enc.compress(to_bytes(q, resolved)?)),
|
||||
move |q| to_bytes(q, resolved),
|
||||
)
|
||||
.await)
|
||||
}
|
||||
@@ -80,11 +76,10 @@ fn output_to_bytes(out: brk_types::SeriesOutput) -> BrkResult<Bytes> {
|
||||
async fn data_handler(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Extension(addr): Extension<SocketAddr>,
|
||||
Query(params): Query<SeriesSelection>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Response> {
|
||||
serve(state, uri, headers, addr, params, |q, r| {
|
||||
serve(state, uri, headers, params, |q, r| {
|
||||
output_to_bytes(q.format(r)?)
|
||||
})
|
||||
.await
|
||||
@@ -93,11 +88,10 @@ async fn data_handler(
|
||||
async fn data_raw_handler(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Extension(addr): Extension<SocketAddr>,
|
||||
Query(params): Query<SeriesSelection>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Response> {
|
||||
serve(state, uri, headers, addr, params, |q, r| {
|
||||
serve(state, uri, headers, params, |q, r| {
|
||||
output_to_bytes(q.format_raw(r)?)
|
||||
})
|
||||
.await
|
||||
@@ -113,7 +107,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
"/api/series",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.series_catalog().clone())).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.series_catalog().clone())).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_series_tree")
|
||||
@@ -136,7 +130,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.series_count())).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.series_count())).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_series_count")
|
||||
@@ -156,7 +150,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.indexes().to_vec())).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| Ok(q.indexes().to_vec())).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_indexes")
|
||||
@@ -178,7 +172,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Query(pagination): Query<Pagination>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, move |q| Ok(q.series_list(pagination))).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, move |q| Ok(q.series_list(pagination))).await
|
||||
},
|
||||
|op| op
|
||||
.id("list_series")
|
||||
@@ -198,7 +192,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Query(query): Query<SearchQuery>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, move |q| Ok(q.search_series(&query))).await
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, move |q| Ok(q.search_series(&query))).await
|
||||
},
|
||||
|op| op
|
||||
.id("search_series")
|
||||
@@ -220,7 +214,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Path(path): Path<SeriesParam>
|
||||
| {
|
||||
state.cached_json(&headers, CacheStrategy::Deploy, &uri, move |q| {
|
||||
state.respond_json(&headers, CacheStrategy::Deploy, &uri, move |q| {
|
||||
q.series_info(&path.series).ok_or_else(|| q.series_not_found_error(&path.series))
|
||||
}).await
|
||||
},
|
||||
@@ -242,7 +236,6 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri,
|
||||
headers: HeaderMap,
|
||||
addr: Extension<SocketAddr>,
|
||||
state: State<AppState>,
|
||||
Path(path): Path<SeriesNameWithIndex>,
|
||||
Query(range): Query<DataRangeFormat>|
|
||||
@@ -250,7 +243,6 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
data_handler(
|
||||
uri,
|
||||
headers,
|
||||
addr,
|
||||
Query(SeriesSelection::from((path.index, path.series, range))),
|
||||
state,
|
||||
)
|
||||
@@ -276,7 +268,6 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri,
|
||||
headers: HeaderMap,
|
||||
addr: Extension<SocketAddr>,
|
||||
state: State<AppState>,
|
||||
Path(path): Path<SeriesNameWithIndex>,
|
||||
Query(range): Query<DataRangeFormat>|
|
||||
@@ -284,7 +275,6 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
data_raw_handler(
|
||||
uri,
|
||||
headers,
|
||||
addr,
|
||||
Query(SeriesSelection::from((path.index, path.series, range))),
|
||||
state,
|
||||
)
|
||||
@@ -314,7 +304,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Path(path): Path<SeriesNameWithIndex>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.latest(&path.series, path.index)
|
||||
})
|
||||
.await
|
||||
@@ -340,7 +330,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Path(path): Path<SeriesNameWithIndex>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.len(&path.series, path.index)
|
||||
})
|
||||
.await
|
||||
@@ -364,7 +354,7 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>,
|
||||
Path(path): Path<SeriesNameWithIndex>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.version(&path.series, path.index)
|
||||
})
|
||||
.await
|
||||
@@ -382,8 +372,8 @@ impl ApiSeriesRoutes for ApiRouter<AppState> {
|
||||
.api_route(
|
||||
"/api/series/bulk",
|
||||
get_with(
|
||||
|uri, headers, addr, query, state| async move {
|
||||
data_handler(uri, headers, addr, query, state).await.into_response()
|
||||
|uri, headers, query, state| async move {
|
||||
data_handler(uri, headers, query, state).await.into_response()
|
||||
},
|
||||
|op| op
|
||||
.id("get_series_bulk")
|
||||
|
||||
@@ -5,11 +5,10 @@
|
||||
//! in legacy mode (registered by metrics endpoints that emit the old format).
|
||||
//! - `add_series_legacy_routes`: the deprecated `/api/series/cost-basis/*` URLs.
|
||||
|
||||
use std::{collections::BTreeMap, net::SocketAddr};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use aide::axum::{ApiRouter, routing::get_with};
|
||||
use axum::{
|
||||
Extension,
|
||||
body::Bytes,
|
||||
extract::{Path, Query, State},
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
@@ -40,12 +39,11 @@ pub const SUNSET: &str = "2027-01-01T00:00:00Z";
|
||||
pub async fn handler(
|
||||
uri: Uri,
|
||||
headers: HeaderMap,
|
||||
Extension(addr): Extension<SocketAddr>,
|
||||
Query(params): Query<SeriesSelection>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Response> {
|
||||
let mut response =
|
||||
super::series::serve(state, uri, headers, addr, params, legacy_bytes).await?;
|
||||
super::series::serve(state, uri, headers, params, legacy_bytes).await?;
|
||||
if response.status() == StatusCode::OK {
|
||||
response.headers_mut().insert_deprecation(SUNSET);
|
||||
}
|
||||
@@ -152,7 +150,7 @@ impl ApiSeriesLegacyRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| q.urpd_cohorts())
|
||||
.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| q.urpd_cohorts())
|
||||
.await
|
||||
},
|
||||
|op| {
|
||||
@@ -179,7 +177,7 @@ impl ApiSeriesLegacyRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.urpd_dates(¶ms.cohort)
|
||||
})
|
||||
.await
|
||||
@@ -208,9 +206,9 @@ impl ApiSeriesLegacyRoutes for ApiRouter<AppState> {
|
||||
Path(params): Path<CostBasisParams>,
|
||||
Query(query): Query<CostBasisQuery>,
|
||||
State(state): State<AppState>| {
|
||||
let strategy = state.date_cache(Version::ONE, params.date);
|
||||
let strategy = state.date_strategy(Version::ONE, params.date);
|
||||
state
|
||||
.cached_json(&headers, strategy, &uri, move |q| {
|
||||
.respond_json(&headers, strategy, &uri, move |q| {
|
||||
cost_basis_formatted(
|
||||
q,
|
||||
¶ms.cohort,
|
||||
|
||||
@@ -4,10 +4,15 @@ use aide::axum::{ApiRouter, routing::get_with};
|
||||
use axum::{
|
||||
extract::State,
|
||||
http::{HeaderMap, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_types::{DiskUsage, Health, SyncStatus};
|
||||
|
||||
use crate::{CacheStrategy, VERSION, extended::TransformResponseExtended, params::Empty};
|
||||
use crate::{
|
||||
CacheStrategy, VERSION,
|
||||
extended::{HeaderMapExtended, TransformResponseExtended},
|
||||
params::Empty,
|
||||
};
|
||||
|
||||
use super::AppState;
|
||||
|
||||
@@ -20,7 +25,7 @@ impl ServerRoutes for ApiRouter<AppState> {
|
||||
self.api_route(
|
||||
"/health",
|
||||
get_with(
|
||||
async |_: Empty, State(state): State<AppState>| -> axum::Json<Health> {
|
||||
async |_: Empty, State(state): State<AppState>| -> Response {
|
||||
let uptime = state.started_instant.elapsed();
|
||||
let started_at = state.started_at.to_string();
|
||||
let sync = state
|
||||
@@ -33,7 +38,7 @@ impl ServerRoutes for ApiRouter<AppState> {
|
||||
})
|
||||
.await
|
||||
.expect("health sync task panicked");
|
||||
axum::Json(Health {
|
||||
let mut response = axum::Json(Health {
|
||||
status: Cow::Borrowed("healthy"),
|
||||
service: Cow::Borrowed("brk"),
|
||||
version: Cow::Borrowed(VERSION),
|
||||
@@ -42,6 +47,11 @@ impl ServerRoutes for ApiRouter<AppState> {
|
||||
uptime_seconds: uptime.as_secs(),
|
||||
sync,
|
||||
})
|
||||
.into_response();
|
||||
let h = response.headers_mut();
|
||||
h.insert_cache_control("no-store");
|
||||
h.insert_cdn_cache_control("no-store");
|
||||
response
|
||||
},
|
||||
|op| {
|
||||
op.id("get_health")
|
||||
@@ -57,7 +67,7 @@ impl ServerRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Deploy, &uri, |_| {
|
||||
.respond_json(&headers, CacheStrategy::Deploy, &uri, |_| {
|
||||
Ok(env!("CARGO_PKG_VERSION"))
|
||||
})
|
||||
.await
|
||||
@@ -77,7 +87,7 @@ impl ServerRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
let tip_height = q.client().get_last_height()?;
|
||||
Ok(q.sync_status(tip_height))
|
||||
})
|
||||
@@ -102,7 +112,7 @@ impl ServerRoutes for ApiRouter<AppState> {
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
let brk_path = state.data_path.clone();
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
let brk_bytes = dir_size(&brk_path)?;
|
||||
let bitcoin_bytes = dir_size(q.blocks_dir())?;
|
||||
Ok(DiskUsage::new(brk_bytes, bitcoin_bytes))
|
||||
|
||||
@@ -28,7 +28,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
"/api/tx-index/{index}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxIndexParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_text(&headers, CacheStrategy::Immutable(Version::ONE), &uri, move |q| q.txid_by_index(param.index).map(|t| t.to_string())).await
|
||||
state.respond_text(&headers, CacheStrategy::Immutable(Version::ONE), &uri, move |q| q.txid_by_index(param.index).map(|t| t.to_string())).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_by_index")
|
||||
@@ -46,7 +46,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/cpfp/{txid}",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.cpfp(¶m.txid)).await
|
||||
state.respond_json(&headers, state.tx_strategy(Version::ONE, ¶m.txid), &uri, move |q| q.cpfp(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_cpfp")
|
||||
@@ -64,7 +64,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
"/api/v1/tx/{txid}/rbf",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.mempool_cache(), &uri, move |q| q.tx_rbf(¶m.txid)).await
|
||||
state.respond_json(&headers, state.mempool_strategy(), &uri, move |q| q.tx_rbf(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_rbf")
|
||||
@@ -88,7 +88,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction(¶m.txid)).await
|
||||
state.respond_json(&headers, state.tx_strategy(Version::ONE, ¶m.txid), &uri, move |q| q.transaction(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx")
|
||||
@@ -114,7 +114,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_text(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_hex(¶m.txid)).await
|
||||
state.respond_text(&headers, state.tx_strategy(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_hex(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_hex")
|
||||
@@ -134,7 +134,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
"/api/tx/{txid}/merkleblock-proof",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_text(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.merkleblock_proof(¶m.txid)).await
|
||||
state.respond_text(&headers, state.tx_strategy(Version::ONE, ¶m.txid), &uri, move |q| q.merkleblock_proof(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_merkleblock_proof")
|
||||
@@ -152,7 +152,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
"/api/tx/{txid}/merkle-proof",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.merkle_proof(¶m.txid)).await
|
||||
state.respond_json(&headers, state.tx_strategy(Version::ONE, ¶m.txid), &uri, move |q| q.merkle_proof(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_merkle_proof")
|
||||
@@ -177,7 +177,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let v = Version::ONE;
|
||||
state.cached_json_optimistic(&headers, CacheStrategy::Immutable(v), &uri, move |q| {
|
||||
state.respond_json_optimistic(&headers, CacheStrategy::Immutable(v), &uri, move |q| {
|
||||
let outspend = q.outspend(&path.txid, path.vout)?;
|
||||
let strategy = if outspend.is_deeply_spent(q.height()) {
|
||||
CacheStrategy::Immutable(v)
|
||||
@@ -212,7 +212,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
let v = Version::ONE;
|
||||
state.cached_json_optimistic(&headers, CacheStrategy::Immutable(v), &uri, move |q| {
|
||||
state.respond_json_optimistic(&headers, CacheStrategy::Immutable(v), &uri, move |q| {
|
||||
let outspends = q.outspends(¶m.txid)?;
|
||||
let height = q.height();
|
||||
let all_deep = outspends.iter().all(|o| o.is_deeply_spent(height));
|
||||
@@ -238,7 +238,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
"/api/tx/{txid}/raw",
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, Path(param): Path<TxidParam>, _: Empty, State(state): State<AppState>| {
|
||||
state.cached_bytes(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_raw(¶m.txid)).await
|
||||
state.respond_bytes(&headers, state.tx_strategy(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_raw(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_raw")
|
||||
@@ -262,7 +262,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>
|
||||
| {
|
||||
state.cached_json(&headers, state.tx_cache(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_status(¶m.txid)).await
|
||||
state.respond_json(&headers, state.tx_strategy(Version::ONE, ¶m.txid), &uri, move |q| q.transaction_status(¶m.txid)).await
|
||||
},
|
||||
|op| op
|
||||
.id("get_tx_status")
|
||||
@@ -284,7 +284,7 @@ impl TxRoutes for ApiRouter<AppState> {
|
||||
async |uri: Uri, headers: HeaderMap, State(state): State<AppState>| -> Result<Response> {
|
||||
let params = TxidsParam::from_query(uri.query().unwrap_or(""))
|
||||
.map_err(Error::bad_request)?;
|
||||
Ok(state.cached_json(&headers, state.mempool_cache(), &uri, move |q| q.transaction_times(¶ms.txids)).await)
|
||||
Ok(state.respond_json(&headers, state.mempool_strategy(), &uri, move |q| q.transaction_times(¶ms.txids)).await)
|
||||
},
|
||||
|op| op
|
||||
.id("get_transaction_times")
|
||||
|
||||
@@ -24,7 +24,7 @@ impl ApiUrpdRoutes for ApiRouter<AppState> {
|
||||
get_with(
|
||||
async |uri: Uri, headers: HeaderMap, _: Empty, State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Deploy, &uri, |q| q.urpd_cohorts())
|
||||
.respond_json(&headers, CacheStrategy::Deploy, &uri, |q| q.urpd_cohorts())
|
||||
.await
|
||||
},
|
||||
|op| {
|
||||
@@ -50,7 +50,7 @@ impl ApiUrpdRoutes for ApiRouter<AppState> {
|
||||
_: Empty,
|
||||
State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.urpd_dates(¶ms.cohort)
|
||||
})
|
||||
.await
|
||||
@@ -79,7 +79,7 @@ impl ApiUrpdRoutes for ApiRouter<AppState> {
|
||||
Query(query): Query<UrpdQuery>,
|
||||
State(state): State<AppState>| {
|
||||
state
|
||||
.cached_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
.respond_json(&headers, CacheStrategy::Tip, &uri, move |q| {
|
||||
q.urpd_latest(¶ms.cohort, query.aggregation)
|
||||
})
|
||||
.await
|
||||
@@ -108,9 +108,9 @@ impl ApiUrpdRoutes for ApiRouter<AppState> {
|
||||
Path(params): Path<UrpdParams>,
|
||||
Query(query): Query<UrpdQuery>,
|
||||
State(state): State<AppState>| {
|
||||
let strategy = state.date_cache(Version::ONE, params.date);
|
||||
let strategy = state.date_strategy(Version::ONE, params.date);
|
||||
state
|
||||
.cached_json(&headers, strategy, &uri, move |q| {
|
||||
.respond_json(&headers, strategy, &uri, move |q| {
|
||||
q.urpd_at(¶ms.cohort, params.date, query.aggregation)
|
||||
})
|
||||
.await
|
||||
|
||||
Reference in New Issue
Block a user