Refactor to clean-up axum server implementation
This commit is contained in:
parent
09e538872d
commit
4b16f39b4d
10 changed files with 1308 additions and 57 deletions
1256
Cargo.lock
generated
1256
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -6,6 +6,7 @@ edition = "2024"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
sqlx = { version = "0.8.6", features = ["runtime-tokio", "postgres", "macros"] }
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tower = "0.5"
|
tower = "0.5"
|
||||||
tower-http = { version = "0.6", features = ["trace"] }
|
tower-http = { version = "0.6", features = ["trace"] }
|
||||||
|
|
|
||||||
17
src/env.rs
Normal file
17
src/env.rs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Env {
|
||||||
|
pub postgres_connection_string: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Env {
|
||||||
|
pub fn parse_env() -> Env {
|
||||||
|
let postgres_connection_string = env::var("POSTGRES_CONNECTION_STRING")
|
||||||
|
.expect("Missing POSTGRES_CONNECTION_STRING as an environment variable");
|
||||||
|
|
||||||
|
Env {
|
||||||
|
postgres_connection_string,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,9 +1,12 @@
|
||||||
|
pub mod env;
|
||||||
pub mod routes;
|
pub mod routes;
|
||||||
|
pub mod state;
|
||||||
pub mod votes;
|
pub mod votes;
|
||||||
|
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
|
use state::AppState;
|
||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::TraceLayer;
|
||||||
|
|
||||||
pub fn app() -> Router {
|
pub fn app(state: AppState) -> Router {
|
||||||
routes::router().layer(TraceLayer::new_for_http())
|
routes::router(state).layer(TraceLayer::new_for_http())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||||
|
use uprs::state::AppState;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
|
|
@ -13,5 +14,7 @@ async fn main() {
|
||||||
|
|
||||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||||
tracing::info!("listening on {}", listener.local_addr().unwrap());
|
tracing::info!("listening on {}", listener.local_addr().unwrap());
|
||||||
axum::serve(listener, uprs::app()).await.unwrap();
|
axum::serve(listener, uprs::app(AppState::new().await))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,12 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use axum::{Router, routing::get};
|
use axum::{Router, routing::get};
|
||||||
|
|
||||||
use crate::votes::{repository::VoteRepository, service::VoteService};
|
use crate::state::AppState;
|
||||||
|
|
||||||
pub fn router() -> Router {
|
|
||||||
let vote_service = Arc::new(VoteService::new(VoteRepository::new()));
|
|
||||||
|
|
||||||
|
pub fn router(state: AppState) -> Router {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/health", get(health))
|
.route("/health", get(health))
|
||||||
.merge(crate::votes::handlers::router(vote_service))
|
.merge(crate::votes::handlers::router())
|
||||||
|
.with_state(state)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn health() -> &'static str {
|
async fn health() -> &'static str {
|
||||||
|
|
|
||||||
19
src/state.rs
Normal file
19
src/state.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
use sqlx::PgPool;
|
||||||
|
|
||||||
|
use crate::env::Env;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct AppState {
|
||||||
|
pub db: PgPool,
|
||||||
|
pub env: Env,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AppState {
|
||||||
|
pub async fn new() -> Self {
|
||||||
|
let env = Env::parse_env();
|
||||||
|
let db = sqlx::PgPool::connect(&env.postgres_connection_string)
|
||||||
|
.await
|
||||||
|
.expect("Unable to connect to postgres db");
|
||||||
|
AppState { db, env }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,29 +1,13 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
Router,
|
Router,
|
||||||
extract::{Path, State},
|
extract::{Path, State},
|
||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{dto::CreateVoteRequest, service::VoteService};
|
use crate::state::AppState;
|
||||||
|
|
||||||
pub fn router(service: Arc<VoteService>) -> Router {
|
use super::dto::CreateVoteRequest;
|
||||||
|
|
||||||
|
pub fn router() -> Router<AppState> {
|
||||||
Router::new()
|
Router::new()
|
||||||
.route("/votes", get(list))
|
|
||||||
.route("/votes/{id}", get(get_by_id))
|
|
||||||
.route("/votes", post(create))
|
|
||||||
.with_state(service)
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn list(State(service): State<Arc<VoteService>>) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn get_by_id(State(service): State<Arc<VoteService>>, Path(id): Path<u64>) {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn create(State(service): State<Arc<VoteService>>, body: axum::Json<CreateVoteRequest>) {
|
|
||||||
todo!()
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,3 @@
|
||||||
|
use sqlx::PgPool;
|
||||||
|
|
||||||
use super::model::Vote;
|
use super::model::Vote;
|
||||||
|
|
||||||
pub struct VoteRepository {}
|
|
||||||
|
|
||||||
impl VoteRepository {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,3 @@
|
||||||
use super::{
|
use crate::state::AppState;
|
||||||
dto::{CreateVoteRequest, VoteResponse},
|
|
||||||
repository::VoteRepository,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct VoteService {
|
use super::dto::{CreateVoteRequest, VoteResponse};
|
||||||
repository: VoteRepository,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VoteService {
|
|
||||||
pub fn new(repository: VoteRepository) -> Self {
|
|
||||||
Self { repository }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue