Skip to content

Commit dd4ab57

Browse files
Implement book list with Pagination
1 parent e9b4fbc commit dd4ab57

File tree

4 files changed

+95
-10
lines changed

4 files changed

+95
-10
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
use std::sync::Arc;
2+
use warp::Filter;
3+
4+
use application::books::{
5+
BookService, ListBooksQueryHandler, ListBooksQueryHandlerTrait,
6+
};
7+
use common::server_error::ServerError;
8+
use domain::queries::ListBooks;
9+
10+
pub fn route<T>(
11+
handler: Arc<ListBooksQueryHandler<T>>,
12+
) -> impl Filter<Extract = impl warp::Reply, Error = warp::Rejection> + Clone
13+
where
14+
T: BookService + Send + Sync + 'static,
15+
{
16+
// GET /books
17+
warp::path!("books" / "list")
18+
.and(warp::get())
19+
.and(warp::query::<ListBooks>())
20+
.and(with_handler(handler))
21+
.and_then(handle_get_all_books)
22+
}
23+
24+
fn with_handler<T>(
25+
handler: Arc<ListBooksQueryHandler<T>>,
26+
) -> impl Filter<
27+
Extract = (Arc<ListBooksQueryHandler<T>>,),
28+
Error = std::convert::Infallible,
29+
> + Clone
30+
where
31+
T: BookService + Send + Sync + 'static,
32+
{
33+
warp::any().map(move || handler.clone())
34+
}
35+
36+
async fn handle_get_all_books<T>(
37+
query: ListBooks,
38+
handler: Arc<ListBooksQueryHandler<T>>,
39+
) -> Result<impl warp::Reply, warp::Rejection>
40+
where
41+
T: BookService + Send + Sync + 'static,
42+
{
43+
match handler.handle(query).await {
44+
Ok(books) => Ok(warp::reply::json(&books)),
45+
Err(_) => Err(warp::reject::custom(ServerError)),
46+
}
47+
}

packages/api/src/endpoints/books/mod.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@ mod create;
22
mod delete;
33
mod get_all;
44
mod get_by_id;
5+
mod list;
56
mod update;
67

78
use std::sync::Arc;
89
use warp::Filter;
910

1011
use application::books::{
11-
command_handlers::CreateBookCommandHandler,
12-
command_handlers::DeleteBookCommandHandler,
13-
command_handlers::UpdateBookCommandHandler,
14-
query_handlers::GetAllBooksQueryHandler,
15-
query_handlers::GetBookByIdQueryHandler,
12+
CreateBookCommandHandler, DeleteBookCommandHandler, GetAllBooksQueryHandler,
13+
GetBookByIdQueryHandler, ListBooksQueryHandler, UpdateBookCommandHandler,
1614
};
1715
use infrastructure::{
1816
repositories::book_repository::BookRepository,
@@ -29,6 +27,7 @@ pub fn register(
2927
let create_handler = Arc::new(CreateBookCommandHandler::new(service.clone()));
3028
let update_handler = Arc::new(UpdateBookCommandHandler::new(service.clone()));
3129
let delete_handler = Arc::new(DeleteBookCommandHandler::new(service.clone()));
30+
let list_handler = Arc::new(ListBooksQueryHandler::new(service.clone()));
3231
let get_all_handler = Arc::new(GetAllBooksQueryHandler::new(service.clone()));
3332
let get_by_id_handler =
3433
Arc::new(GetBookByIdQueryHandler::new(service.clone()));
@@ -37,10 +36,14 @@ pub fn register(
3736
let create = create::route(create_handler);
3837
let update = update::route(update_handler);
3938
let delete = delete::route(delete_handler);
39+
let list = list::route(list_handler);
4040
let get_all = get_all::route(get_all_handler);
4141
let get_by_id = get_by_id::route(get_by_id_handler);
4242

43-
let routes = create.or(update).or(delete).or(get_all).or(get_by_id);
44-
45-
routes
43+
create
44+
.or(update)
45+
.or(delete)
46+
.or(list)
47+
.or(get_all)
48+
.or(get_by_id)
4649
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use std::sync::Arc;
2+
3+
use async_trait::async_trait;
4+
use common::{Paged, app_error::AppError};
5+
use domain::{aggregate::book::Book, queries::ListBooks};
6+
7+
use crate::books::BookService;
8+
9+
#[async_trait]
10+
pub trait ListBooksQueryHandlerTrait: Send + Sync {
11+
async fn handle(&self, query: ListBooks) -> Result<Paged<Book>, AppError>;
12+
}
13+
14+
pub struct ListBooksQueryHandler<T: BookService> {
15+
service: Arc<T>,
16+
}
17+
18+
impl<T: BookService> ListBooksQueryHandler<T> {
19+
pub fn new(service: Arc<T>) -> Self {
20+
Self { service }
21+
}
22+
}
23+
24+
#[async_trait]
25+
impl<T: BookService> ListBooksQueryHandlerTrait for ListBooksQueryHandler<T> {
26+
async fn handle(&self, pager: ListBooks) -> Result<Paged<Book>, AppError> {
27+
self
28+
.service
29+
.list(pager.page.unwrap_or(1), pager.page_size.unwrap_or(10))
30+
.await
31+
.map_err(|e| AppError::DatabaseError(e.to_string()))
32+
}
33+
}

packages/domain/src/queries/book.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ pub struct GetAllBooksQuery;
1010

1111
#[derive(Debug, Clone, Serialize, Deserialize)]
1212
pub struct ListBooks {
13-
pub page: u64,
14-
pub page_size: u64,
13+
#[serde(default)]
14+
pub page: Option<u64>,
15+
#[serde(default)]
16+
pub page_size: Option<u64>,
1517
}
1618

1719
#[derive(Debug, Clone, Serialize, Deserialize)]

0 commit comments

Comments
 (0)