Skip to content

Commit

Permalink
feat(api): support sort option in queries (#363)
Browse files Browse the repository at this point in the history
* Add serde rename on fields

* Impl sort in history queries

Co-authored-by: Jochen Görtler <[email protected]>
  • Loading branch information
Alex6323 and grtlr authored Jun 29, 2022
1 parent 5a8bab7 commit db116f3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 9 deletions.
2 changes: 2 additions & 0 deletions bin/inx-chronicle/src/api/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ pub enum ParseError {
#[allow(dead_code)]
#[error("Invalid cursor")]
BadPagingState,
#[error("Invalid sort order descriptor")]
BadSortDescriptor,
#[cfg(feature = "stardust")]
#[error(transparent)]
BeeBlockStardust(#[from] bee_block_stardust::Error),
Expand Down
63 changes: 58 additions & 5 deletions bin/inx-chronicle/src/api/stardust/history/extractors.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,54 @@
// Copyright 2022 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

use std::str::FromStr;

use async_trait::async_trait;
use axum::extract::{FromRequest, Query};
use chronicle::types::stardust::block::OutputId;
use chronicle::{db::collections::SortOrder, types::stardust::block::OutputId};
use serde::Deserialize;

use crate::api::{error::ParseError, ApiError};

const DEFAULT_PAGE_SIZE: usize = 100;

#[derive(Clone, Debug)]
pub enum Sort {
Ascending,
Descending,
}

impl Default for Sort {
fn default() -> Self {
Self::Ascending
}
}

impl FromStr for Sort {
type Err = ParseError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"asc" => Ok(Self::Ascending),
"desc" => Ok(Self::Descending),
_ => Err(ParseError::BadSortDescriptor),
}
}
}

impl From<Sort> for SortOrder {
fn from(sort: Sort) -> Self {
match sort {
Sort::Ascending => Self::Oldest,
Sort::Descending => Self::Newest,
}
}
}

#[derive(Clone)]
pub struct HistoryByAddressPagination {
pub page_size: usize,
pub sort: Sort,
pub start_milestone_index: Option<u32>,
pub start_output_id: Option<OutputId>,
}
Expand All @@ -22,6 +58,7 @@ pub struct HistoryByAddressPagination {
pub struct HistoryByAddressPaginationQuery {
#[serde(rename = "pageSize")]
pub page_size: Option<usize>,
pub sort: Option<String>,
#[serde(rename = "startMilestoneIndex")]
pub start_milestone_index: Option<u32>,
pub cursor: Option<String>,
Expand All @@ -34,6 +71,7 @@ impl<B: Send> FromRequest<B> for HistoryByAddressPagination {
async fn from_request(req: &mut axum::extract::RequestParts<B>) -> Result<Self, Self::Rejection> {
let Query(HistoryByAddressPaginationQuery {
mut page_size,
sort,
mut start_milestone_index,
cursor,
}) = Query::<HistoryByAddressPaginationQuery>::from_request(req)
Expand All @@ -52,6 +90,11 @@ impl<B: Send> FromRequest<B> for HistoryByAddressPagination {
}
Ok(HistoryByAddressPagination {
page_size: page_size.unwrap_or(DEFAULT_PAGE_SIZE),
sort: if let Some(sort) = sort {
sort.parse().map_err(ApiError::bad_parse)?
} else {
Sort::default()
},
start_milestone_index,
start_output_id,
})
Expand All @@ -61,6 +104,7 @@ impl<B: Send> FromRequest<B> for HistoryByAddressPagination {
#[derive(Clone)]
pub struct HistoryByMilestonePagination {
pub page_size: usize,
pub sort: Sort,
pub start_output_id: Option<OutputId>,
}

Expand All @@ -69,6 +113,7 @@ pub struct HistoryByMilestonePagination {
pub struct HistoryByMilestonePaginationQuery {
#[serde(rename = "pageSize")]
pub page_size: Option<usize>,
pub sort: Option<String>,
pub cursor: Option<String>,
}

Expand All @@ -77,10 +122,13 @@ impl<B: Send> FromRequest<B> for HistoryByMilestonePagination {
type Rejection = ApiError;

async fn from_request(req: &mut axum::extract::RequestParts<B>) -> Result<Self, Self::Rejection> {
let Query(HistoryByMilestonePaginationQuery { mut page_size, cursor }) =
Query::<HistoryByMilestonePaginationQuery>::from_request(req)
.await
.map_err(ApiError::QueryError)?;
let Query(HistoryByMilestonePaginationQuery {
mut page_size,
sort,
cursor,
}) = Query::<HistoryByMilestonePaginationQuery>::from_request(req)
.await
.map_err(ApiError::QueryError)?;
let mut start_output_id = None;
if let Some(cursor) = cursor {
let parts = cursor.split('.').collect::<Vec<_>>();
Expand All @@ -93,6 +141,11 @@ impl<B: Send> FromRequest<B> for HistoryByMilestonePagination {
}
Ok(HistoryByMilestonePagination {
page_size: page_size.unwrap_or(DEFAULT_PAGE_SIZE),
sort: if let Some(sort) = sort {
sort.parse().map_err(ApiError::bad_parse)?
} else {
Sort::default()
},
start_output_id,
})
}
Expand Down
9 changes: 5 additions & 4 deletions bin/inx-chronicle/src/api/stardust/history/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::str::FromStr;

use axum::{extract::Path, routing::get, Extension, Router};
use chronicle::{
db::{collections::SortOrder, MongoDb},
db::MongoDb,
types::{stardust::block::Address, tangle::MilestoneIndex},
};
use futures::{StreamExt, TryStreamExt};
Expand All @@ -32,6 +32,7 @@ async fn transactions_by_address_history(
Path(address): Path<String>,
HistoryByAddressPagination {
page_size,
sort,
start_milestone_index,
start_output_id,
}: HistoryByAddressPagination,
Expand All @@ -45,8 +46,7 @@ async fn transactions_by_address_history(
page_size + 1,
start_milestone_index.map(Into::into),
start_output_id,
// TODO: Allow specifying sort in query
SortOrder::Newest,
sort.into(),
)
.await?;

Expand Down Expand Up @@ -83,13 +83,14 @@ async fn transactions_by_milestone_history(
Path(milestone_index): Path<String>,
HistoryByMilestonePagination {
page_size,
sort,
start_output_id,
}: HistoryByMilestonePagination,
) -> ApiResult<TransactionsPerMilestoneResponse> {
let milestone_index = MilestoneIndex::from_str(&milestone_index).map_err(ApiError::bad_parse)?;

let mut record_stream = database
.stream_ledger_updates_at_index_paginated(milestone_index, page_size + 1, start_output_id, SortOrder::Newest)
.stream_ledger_updates_at_index_paginated(milestone_index, page_size + 1, start_output_id, sort.into())
.await?;

// Take all of the requested records first
Expand Down

0 comments on commit db116f3

Please sign in to comment.