Skip to content

Commit

Permalink
Add get questions handler
Browse files Browse the repository at this point in the history
  • Loading branch information
weigo0510 committed Apr 11, 2024
1 parent 8f26702 commit c0fa26e
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 8 deletions.
27 changes: 25 additions & 2 deletions src/handlers/question.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
use axum::{extract::State, Json};
use axum::{
extract::{Query, State},
Json,
};
use tracing::{event, instrument, Level};

use crate::{
common::error::Error,
models::question::{NewQuestion, Question},
models::{
question::{NewQuestion, Question},
Pagination,
},
repositories::store::Store,
};

Expand All @@ -20,3 +26,20 @@ pub async fn add_question(

Ok(Json(res))
}

#[instrument]
pub async fn get_questions(
State(store): State<Store>,
pagination: Option<Query<Pagination>>,
) -> Result<Json<Vec<Question>>, Error> {
event!(target:"axum-web-demo", Level::INFO, "get pagination questions");
let Query(pagination) = pagination.unwrap_or_default();
let offset: i64 = pagination.offset.unwrap_or(0);
let limit: i64 = pagination.limit.unwrap_or(100);
let res: Vec<Question> = match store.get_questions(offset, limit).await {
Ok(res) => res,
Err(e) => return Err(e),
};

Ok(Json(res))
}
8 changes: 8 additions & 0 deletions src/models/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
use serde::Deserialize;

pub mod question;

#[derive(Debug, Deserialize, Default)]
pub struct Pagination {
pub offset: Option<i64>,
pub limit: Option<i64>,
}
23 changes: 23 additions & 0 deletions src/repositories/store.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use axum::Json;
use sqlx::{
postgres::{PgPoolOptions, PgRow},
PgPool, Row,
};
use tracing::event;

use crate::{
common::error::Error,
Expand Down Expand Up @@ -53,4 +55,25 @@ impl Store {
}
}
}

pub async fn get_questions(&self, offset: i64, limit: i64) -> Result<Vec<Question>, Error> {
match sqlx::query("SELECT * from questions offset $1 limit $2")
.bind(offset)
.bind(limit)
.map(|row: PgRow| Question {
id: QuestionId(row.get("id")),
title: row.get("title"),
content: row.get("content"),
tags: row.get("tags"),
})
.fetch_all(&self.connection)
.await
{
Ok(questions) => Ok(questions),
Err(e) => {
event!(target:"axum-web-dev", tracing::Level::ERROR, "{:?}", e);
Err(Error::DatabaseQueryError)
}
}
}
}
8 changes: 2 additions & 6 deletions src/routers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,13 @@ use axum::{
};
use tower_http::trace::TraceLayer;

use crate::{
handlers::{health_check_handler, question::add_question},
repositories::store::Store,
};
use crate::{handlers::health_check_handler, repositories::store::Store};

pub mod question;

pub fn create_router(store: Store) -> Router {
Router::new()
.route("/api/healthcheck", get(health_check_handler))
.route("/questions", post(add_question))
.merge(question::create_router(store))
.layer(TraceLayer::new_for_http())
.with_state(store)
}
16 changes: 16 additions & 0 deletions src/routers/question.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use axum::{
routing::{get, post},
Router,
};

use crate::{
handlers::question::{add_question, get_questions},
repositories::store::Store,
};

pub fn create_router(store: Store) -> Router {
Router::new()
.route("/api/questions", post(add_question))
.route("/api/questions", get(get_questions))
.with_state(store)
}

0 comments on commit c0fa26e

Please sign in to comment.