From 0c685d755ccbc1712bda79f8c579bb7bde64d1af Mon Sep 17 00:00:00 2001 From: David Westgate Date: Fri, 26 Apr 2024 19:48:30 -0700 Subject: [PATCH] added axum store state to api routes --- src/api.rs | 25 ++++++++++++++++++++----- src/main.rs | 19 ++++++++++++++----- src/question.rs | 26 ++++++++++++++++++-------- src/questions.json | 2 +- 4 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/api.rs b/src/api.rs index fca9ac3..cb1104d 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,7 +1,11 @@ use axum::{ + extract::{Path, State}, http::StatusCode, response::{IntoResponse, Response}, + Json, }; + +use crate::question::{Question, Store}; /** GET /questions (empty body; return JSON) POST /questions (JSON body; return HTTP status code) @@ -10,24 +14,35 @@ DELETE /questions/:questionId (empty body; return HTTP status code) POST /answers (www-url-encoded body; return HTTP status code) * */ -pub async fn get_questions() -> Response { +pub async fn read_question(State(store): State, Path(id): Path) -> Response { //TODO (StatusCode::OK, " Get Questions").into_response() } -pub async fn post_questions() -> Response { +pub async fn read_all_questions(State(store): State) -> Response { + //TODO + (StatusCode::OK, " Get Questions").into_response() +} +pub async fn create_question( + State(store): State, + Json(question): Json, +) -> Response { //TODO (StatusCode::CREATED, "Post Questions").into_response() } -pub async fn put_questions() -> Response { +pub async fn update_question( + State(store): State, + Path(id): Path, + Json(question): Json, +) -> Response { //TODO (StatusCode::CREATED, "Put Questions..").into_response() } -pub async fn delete_questions() -> Response { +pub async fn delete_question(State(store): State, Path(id): Path) -> Response { //TODO (StatusCode::OK, "Delete Questions..").into_response() } -pub async fn post_answers() -> Response { +pub async fn create_answer(State(store): State /*TODO */) -> Response { //TODO (StatusCode::CREATED, "Post Answers..").into_response() } diff --git a/src/main.rs b/src/main.rs index f3c5d45..ac8fdb5 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,14 @@ mod api; +mod err; +mod question; + use axum::{ http::StatusCode, response::{IntoResponse, Response}, routing::{delete, get, post, put}, Router, }; + use std::net::SocketAddr; async fn handle() -> Response { @@ -13,14 +17,19 @@ async fn handle() -> Response { #[tokio::main] async fn main() { + let store = question::Store::new(); let ip = SocketAddr::new([127, 0, 0, 1].into(), 3000); let listener = tokio::net::TcpListener::bind(ip).await.unwrap(); let apis = Router::new() - .route("/questions", get(api::get_questions)) - .route("/questions", post(api::post_questions)) - .route("/questions/:id", put(api::put_questions)) - .route("/questions", delete(api::delete_questions)) - .route("/answers", post(api::post_answers)); + .route("/question/:id", get(api::read_question)) + .route("/questions", get(api::read_all_questions)) + .route("/question", post(api::create_question)) + .route("/question/:id", put(api::update_question)) + .route("/question/:id", delete(api::delete_question)) + .route("/answers", post(api::create_answer)) + //.nest(path, router) + .with_state(store) + .fallback(err::handler_404); let app = Router::new().route("/", get(handle)).merge(apis); axum::serve(listener, app).await.unwrap(); diff --git a/src/question.rs b/src/question.rs index 8ef47e8..7902539 100644 --- a/src/question.rs +++ b/src/question.rs @@ -1,14 +1,19 @@ use std::collections::HashMap; +use axum::{ + http::StatusCode, + response::{IntoResponse, Response}, + Json, +}; use serde::{Deserialize, Serialize}; - -struct Store { +#[derive(Clone)] +pub(crate) struct Store { questions: HashMap, } impl Store { - fn new() -> Self { + pub fn new() -> Self { Store { questions: Self::init(), } @@ -18,7 +23,7 @@ impl Store { serde_json::from_str(file).expect("can't read questions.json") } - fn add(mut self, question: Question) -> Result { + pub fn add(mut self, question: Question) -> Result { match self.questions.get(&question.id) { Some(_) => Err(format!("Question with id {} already exists", question.id)), None => Ok(self @@ -27,22 +32,22 @@ impl Store { .unwrap()), } } - fn remove(mut self, id: u8) -> Result { + pub fn remove(mut self, id: u8) -> Result { match self.questions.remove(&id) { Some(question) => Ok(question), None => Err(format!("Question with id {} does not exist", id)), } } - fn fetch_one(self, id: u8) -> Result { + pub fn fetch_one(self, id: u8) -> Result { match self.questions.get(&id) { Some(question) => Ok(question.clone()), None => Err(format!("Question with id {} does not exist", id)), } } - fn fetch_all(self) -> Vec { + pub fn fetch_all(self) -> Vec { self.questions.values().cloned().collect() } - fn update(mut self, question: Question) -> Result { + pub fn update(mut self, question: Question) -> Result { match self.questions.get(&question.id) { Some(_) => Ok(self .questions @@ -70,3 +75,8 @@ impl Question { } } } +impl IntoResponse for &Question { + fn into_response(self) -> Response { + (StatusCode::OK, Json(&self)).into_response() + } +} diff --git a/src/questions.json b/src/questions.json index 0345a5e..3b1e3c0 100644 --- a/src/questions.json +++ b/src/questions.json @@ -1,6 +1,6 @@ { "1" : { - "id": "1", + "id": 1, "title": "How?", "content": "Please help!", "tags": ["general"]