server: openapi fixes

This commit is contained in:
nym21
2025-12-16 18:03:23 +01:00
parent 593af69230
commit f7f065c6e0
44 changed files with 279 additions and 286 deletions

View File

@@ -5,7 +5,10 @@ use axum::{
response::Redirect,
routing::get,
};
use brk_types::{Address, AddressStats, AddressTxidsParam, AddressValidation, Txid, Utxo};
use brk_types::{
AddressParam, AddressStats, AddressTxidsParam, AddressValidation, Txid, Utxo,
ValidateAddressParam,
};
use crate::{CacheStrategy, extended::TransformResponseExtended};
@@ -24,10 +27,10 @@ impl AddressRoutes for ApiRouter<AppState> {
"/api/address/{address}",
get_with(async |
headers: HeaderMap,
Path(address): Path<Address>,
Path(path): Path<AddressParam>,
State(state): State<AppState>
| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address(address)).await
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address(path.address)).await
}, |op| op
.addresses_tag()
.summary("Address information")
@@ -43,11 +46,11 @@ impl AddressRoutes for ApiRouter<AppState> {
"/api/address/{address}/txs",
get_with(async |
headers: HeaderMap,
Path(address): Path<Address>,
Path(path): Path<AddressParam>,
Query(params): Query<AddressTxidsParam>,
State(state): State<AppState>
| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_txids(address, params.after_txid, params.limit)).await
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_txids(path.address, params.after_txid, params.limit)).await
}, |op| op
.addresses_tag()
.summary("Address transaction IDs")
@@ -63,10 +66,10 @@ impl AddressRoutes for ApiRouter<AppState> {
"/api/address/{address}/utxo",
get_with(async |
headers: HeaderMap,
Path(address): Path<Address>,
Path(path): Path<AddressParam>,
State(state): State<AppState>
| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_utxos(address)).await
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_utxos(path.address)).await
}, |op| op
.addresses_tag()
.summary("Address UTXOs")
@@ -82,11 +85,11 @@ impl AddressRoutes for ApiRouter<AppState> {
"/api/address/{address}/txs/mempool",
get_with(async |
headers: HeaderMap,
Path(address): Path<Address>,
Path(path): Path<AddressParam>,
State(state): State<AppState>
| {
// Mempool txs for an address - use MaxAge since it's volatile
state.cached_json(&headers, CacheStrategy::MaxAge(5), move |q| q.address_mempool_txids(address)).await
state.cached_json(&headers, CacheStrategy::MaxAge(5), move |q| q.address_mempool_txids(path.address)).await
}, |op| op
.addresses_tag()
.summary("Address mempool transactions")
@@ -101,11 +104,11 @@ impl AddressRoutes for ApiRouter<AppState> {
"/api/address/{address}/txs/chain",
get_with(async |
headers: HeaderMap,
Path(address): Path<Address>,
Path(path): Path<AddressParam>,
Query(params): Query<AddressTxidsParam>,
State(state): State<AppState>
| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_txids(address, params.after_txid, 25)).await
state.cached_json(&headers, CacheStrategy::Height, move |q| q.address_txids(path.address, params.after_txid, 25)).await
}, |op| op
.addresses_tag()
.summary("Address confirmed transactions")
@@ -121,10 +124,10 @@ impl AddressRoutes for ApiRouter<AppState> {
"/api/v1/validate-address/{address}",
get_with(async |
headers: HeaderMap,
Path(address): Path<String>,
Path(path): Path<ValidateAddressParam>,
State(state): State<AppState>
| {
state.cached_json(&headers, CacheStrategy::Static, move |_q| Ok(AddressValidation::from_address(&address))).await
state.cached_json(&headers, CacheStrategy::Static, move |_q| Ok(AddressValidation::from_address(&path.address))).await
}, |op| op
.addresses_tag()
.summary("Validate address")

View File

@@ -7,8 +7,8 @@ use axum::{
};
use brk_query::BLOCK_TXS_PAGE_SIZE;
use brk_types::{
BlockHashPath, BlockHashStartIndexPath, BlockHashTxIndexPath, BlockInfo, BlockStatus,
BlockTimestamp, Height, HeightPath, StartHeightPath, TimestampPath, Transaction, Txid,
BlockHashParam, BlockHashStartIndex, BlockHashTxIndex, BlockInfo, BlockStatus, BlockTimestamp,
HeightParam, StartHeightParam, TimestampParam, Transaction, Txid,
};
use crate::{CacheStrategy, extended::TransformResponseExtended};
@@ -30,7 +30,7 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/block/{hash}",
get_with(
async |headers: HeaderMap,
Path(path): Path<BlockHashPath>,
Path(path): Path<BlockHashParam>,
State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block(&path.hash)).await
},
@@ -52,7 +52,7 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/block/{hash}/status",
get_with(
async |headers: HeaderMap,
Path(path): Path<BlockHashPath>,
Path(path): Path<BlockHashParam>,
State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_status(&path.hash)).await
},
@@ -74,10 +74,9 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/block-height/{height}",
get_with(
async |headers: HeaderMap,
Path(path): Path<HeightPath>,
Path(path): Path<HeightParam>,
State(state): State<AppState>| {
let height = Height::from(path.height);
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_by_height(height)).await
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_by_height(path.height)).await
},
|op| {
op.blocks_tag()
@@ -97,10 +96,9 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/blocks/{start_height}",
get_with(
async |headers: HeaderMap,
Path(path): Path<StartHeightPath>,
Path(path): Path<StartHeightParam>,
State(state): State<AppState>| {
let start_height = path.start_height.map(Height::from);
state.cached_json(&headers, CacheStrategy::Height, move |q| q.blocks(start_height)).await
state.cached_json(&headers, CacheStrategy::Height, move |q| q.blocks(path.start_height)).await
},
|op| {
op.blocks_tag()
@@ -119,7 +117,7 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/block/{hash}/txids",
get_with(
async |headers: HeaderMap,
Path(path): Path<BlockHashPath>,
Path(path): Path<BlockHashParam>,
State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_txids(&path.hash)).await
},
@@ -141,7 +139,7 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/block/{hash}/txs/{start_index}",
get_with(
async |headers: HeaderMap,
Path(path): Path<BlockHashStartIndexPath>,
Path(path): Path<BlockHashStartIndex>,
State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_txs(&path.hash, path.start_index)).await
},
@@ -164,7 +162,7 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/block/{hash}/txid/{index}",
get_with(
async |headers: HeaderMap,
Path(path): Path<BlockHashTxIndexPath>,
Path(path): Path<BlockHashTxIndex>,
State(state): State<AppState>| {
state.cached_text(&headers, CacheStrategy::Height, move |q| q.block_txid_at_index(&path.hash, path.index).map(|t| t.to_string())).await
},
@@ -186,7 +184,7 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/v1/mining/blocks/timestamp/{timestamp}",
get_with(
async |headers: HeaderMap,
Path(path): Path<TimestampPath>,
Path(path): Path<TimestampParam>,
State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.block_by_timestamp(path.timestamp)).await
},
@@ -206,7 +204,7 @@ impl BlockRoutes for ApiRouter<AppState> {
"/api/block/{hash}/raw",
get_with(
async |headers: HeaderMap,
Path(path): Path<BlockHashPath>,
Path(path): Path<BlockHashParam>,
State(state): State<AppState>| {
state.cached_bytes(&headers, CacheStrategy::Height, move |q| q.block_raw(&path.hash)).await
},

View File

@@ -10,7 +10,7 @@ use brk_query::{
};
use brk_traversable::TreeNode;
use brk_types::{
Index, IndexInfo, Limit, Metric, MetricCount, MetricData, MetricWithIndex, Metrics,
Index, IndexInfo, LimitParam, MetricCount, MetricData, MetricParam, MetricWithIndex, Metrics,
};
use crate::{CacheStrategy, extended::TransformResponseExtended};
@@ -109,14 +109,13 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
async |
headers: HeaderMap,
State(state): State<AppState>,
Path(metric): Path<Metric>,
Query(limit): Query<Limit>
Path(path): Path<MetricParam>,
Query(query): Query<LimitParam>
| {
state.cached_json(&headers, CacheStrategy::Static, move |q| Ok(q.match_metric(&metric, limit))).await
state.cached_json(&headers, CacheStrategy::Static, move |q| Ok(q.match_metric(&path.metric, query.limit))).await
},
|op| op
.metrics_tag()
// .path_param::<Metric>()
.summary("Search metrics")
.description("Fuzzy search for metrics by name. Supports partial matches and typos.")
.ok_response::<Vec<String>>()
@@ -129,13 +128,13 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
async |
headers: HeaderMap,
State(state): State<AppState>,
Path(metric): Path<Metric>
Path(path): Path<MetricParam>
| {
state.cached_json(&headers, CacheStrategy::Static, move |q| {
if let Some(indexes) = q.metric_to_indexes(metric.clone()) {
if let Some(indexes) = q.metric_to_indexes(path.metric.clone()) {
return Ok(indexes.clone())
}
Err(q.metric_not_found_error(&metric))
Err(q.metric_not_found_error(&path.metric))
}).await
},
|op| op

View File

@@ -6,9 +6,9 @@ use axum::{
routing::get,
};
use brk_types::{
BlockCountPath, BlockFeeRatesEntry, BlockFeesEntry, BlockRewardsEntry, BlockSizesWeights,
BlockCountParam, BlockFeeRatesEntry, BlockFeesEntry, BlockRewardsEntry, BlockSizesWeights,
DifficultyAdjustment, DifficultyAdjustmentEntry, HashrateSummary, PoolDetail, PoolInfo,
PoolSlugPath, PoolsSummary, RewardStats, TimePeriod,
PoolSlugParam, PoolsSummary, RewardStats, TimePeriodParam,
};
use crate::{CacheStrategy, extended::TransformResponseExtended};
@@ -61,8 +61,8 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/pools/{time_period}",
get_with(
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("{:?}", time_period)), move |q| q.mining_pools(time_period)).await
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("{:?}", path.time_period)), move |q| q.mining_pools(path.time_period)).await
},
|op| {
op.mining_tag()
@@ -77,7 +77,7 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/pool/{slug}",
get_with(
async |headers: HeaderMap, Path(path): Path<PoolSlugPath>, State(state): State<AppState>| {
async |headers: HeaderMap, Path(path): Path<PoolSlugParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(path.slug), move |q| q.pool_detail(path.slug)).await
},
|op| {
@@ -110,8 +110,8 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/hashrate/{time_period}",
get_with(
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("hashrate-{:?}", time_period)), move |q| q.hashrate(Some(time_period))).await
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("hashrate-{:?}", path.time_period)), move |q| q.hashrate(Some(path.time_period))).await
},
|op| {
op.mining_tag()
@@ -142,8 +142,8 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/difficulty-adjustments/{time_period}",
get_with(
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("diff-adj-{:?}", time_period)), move |q| q.difficulty_adjustments(Some(time_period))).await
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("diff-adj-{:?}", path.time_period)), move |q| q.difficulty_adjustments(Some(path.time_period))).await
},
|op| {
op.mining_tag()
@@ -158,8 +158,8 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/blocks/fees/{time_period}",
get_with(
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("fees-{:?}", time_period)), move |q| q.block_fees(time_period)).await
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("fees-{:?}", path.time_period)), move |q| q.block_fees(path.time_period)).await
},
|op| {
op.mining_tag()
@@ -174,8 +174,8 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/blocks/rewards/{time_period}",
get_with(
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("rewards-{:?}", time_period)), move |q| q.block_rewards(time_period)).await
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("rewards-{:?}", path.time_period)), move |q| q.block_rewards(path.time_period)).await
},
|op| {
op.mining_tag()
@@ -190,8 +190,8 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/blocks/fee-rates/{time_period}",
get_with(
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("feerates-{:?}", time_period)), move |q| q.block_fee_rates(time_period)).await
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("feerates-{:?}", path.time_period)), move |q| q.block_fee_rates(path.time_period)).await
},
|op| {
op.mining_tag()
@@ -206,8 +206,8 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/blocks/sizes-weights/{time_period}",
get_with(
async |headers: HeaderMap, Path(time_period): Path<TimePeriod>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("sizes-{:?}", time_period)), move |q| q.block_sizes_weights(time_period)).await
async |headers: HeaderMap, Path(path): Path<TimePeriodParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("sizes-{:?}", path.time_period)), move |q| q.block_sizes_weights(path.time_period)).await
},
|op| {
op.mining_tag()
@@ -222,7 +222,7 @@ impl MiningRoutes for ApiRouter<AppState> {
.api_route(
"/api/v1/mining/reward-stats/{block_count}",
get_with(
async |headers: HeaderMap, Path(path): Path<BlockCountPath>, State(state): State<AppState>| {
async |headers: HeaderMap, Path(path): Path<BlockCountParam>, State(state): State<AppState>| {
state.cached_json(&headers, CacheStrategy::height_with(format!("reward-stats-{}", path.block_count)), move |q| q.reward_stats(path.block_count)).await
},
|op| {

View File

@@ -5,7 +5,7 @@ use axum::{
response::Redirect,
routing::get,
};
use brk_types::{Transaction, TxOutspend, TxStatus, TxidPath, TxidVoutPath};
use brk_types::{Transaction, TxOutspend, TxStatus, TxidParam, TxidVout};
use crate::{CacheStrategy, extended::TransformResponseExtended};
@@ -25,7 +25,7 @@ impl TxRoutes for ApiRouter<AppState> {
get_with(
async |
headers: HeaderMap,
Path(txid): Path<TxidPath>,
Path(txid): Path<TxidParam>,
State(state): State<AppState>
| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.transaction(txid)).await
@@ -48,7 +48,7 @@ impl TxRoutes for ApiRouter<AppState> {
get_with(
async |
headers: HeaderMap,
Path(txid): Path<TxidPath>,
Path(txid): Path<TxidParam>,
State(state): State<AppState>
| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.transaction_status(txid)).await
@@ -71,7 +71,7 @@ impl TxRoutes for ApiRouter<AppState> {
get_with(
async |
headers: HeaderMap,
Path(txid): Path<TxidPath>,
Path(txid): Path<TxidParam>,
State(state): State<AppState>
| {
state.cached_text(&headers, CacheStrategy::Height, move |q| q.transaction_hex(txid)).await
@@ -94,10 +94,10 @@ impl TxRoutes for ApiRouter<AppState> {
get_with(
async |
headers: HeaderMap,
Path(path): Path<TxidVoutPath>,
Path(path): Path<TxidVout>,
State(state): State<AppState>
| {
let txid = TxidPath { txid: path.txid };
let txid = TxidParam { txid: path.txid };
state.cached_json(&headers, CacheStrategy::Height, move |q| q.outspend(txid, path.vout)).await
},
|op| op
@@ -118,7 +118,7 @@ impl TxRoutes for ApiRouter<AppState> {
get_with(
async |
headers: HeaderMap,
Path(txid): Path<TxidPath>,
Path(txid): Path<TxidParam>,
State(state): State<AppState>
| {
state.cached_json(&headers, CacheStrategy::Height, move |q| q.outspends(txid)).await