I am working with Rust and Axum on a simple REST API project. What I am trying to accomplish is to merge a route, http verb, and handler together to mimic what controllers in other languages/frameworks do. Everything is looking really good except that when I launch the server and hit the /projects:9090 endpoint, I receive a 404 error rather than a list or empty list. I suspect that my issue is how I am mutating the router instance.
use crate::state::AppState;
use axum::response::IntoResponse;
use axum::Router;
use serde::{Deserialize, Serialize};
mod create;
mod delete;
mod find_one;
mod health_check;
mod list;
mod update;
const HEALTH_CHECK_PATH: &str = "/health_check";
const PROJECTS_PATH: &str = "/projects";
const PROJECTS_NAME_PATH: &str = "/projects/:name";
#[derive(Clone, Debug)]
pub struct Controller {
pub(crate) router: Router<AppState>,
}
impl Controller {
pub fn new() -> Controller {
let controller = Controller {
router: Router::new(),
};
controller
.create()
.delete()
.find_one()
.health_check()
.list()
.update();
controller
}
}
and here is the list() method...
use crate::state::AppState;
use axum::extract::{Query, State};
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::routing::get;
use axum::Json;
use axum_macros::debug_handler;
use serde::Deserialize;
use crate::controller::{Controller, PROJECTS_PATH};
impl Controller {
pub fn list(&self) -> &Controller {
// #[derive(Debug, Deserialize, Default)]
// pub struct Pagination {
// pub offset: Option<usize>,
// pub limit: Option<usize>,
// }
#[debug_handler]
pub async fn handler(
//pagination: Option<Query<Pagination>>,
State(state): State<AppState>,
) -> impl IntoResponse {
//let Query(_pagination) = pagination.unwrap_or_default();
match state.query_port.read().unwrap().list() {
Ok(res) => (StatusCode::OK, Json(res)).into_response(),
Err(err) => {
(StatusCode::INTERNAL_SERVER_ERROR, Json(err.to_string())).into_response()
}
}
}
let _ = self.router.clone().route(PROJECTS_PATH, get(handler));
self
}
}