From 85765bb3b099e6cf7be4c85ef7e0c3f86baa0f3f Mon Sep 17 00:00:00 2001 From: Kristofers Solo Date: Sat, 21 Jun 2025 16:15:50 +0300 Subject: [PATCH] feat: add router --- {server/configuration => config}/base.toml | 0 {server/configuration => config}/local.toml | 0 .../configuration => config}/productionn.toml | 0 server/src/lib.rs | 8 ++-- server/src/main.rs | 40 ++++++------------- server/src/routes/mod.rs | 25 +++++++++++- server/src/startup.rs | 38 +++++++++++------- 7 files changed, 64 insertions(+), 47 deletions(-) rename {server/configuration => config}/base.toml (100%) rename {server/configuration => config}/local.toml (100%) rename {server/configuration => config}/productionn.toml (100%) diff --git a/server/configuration/base.toml b/config/base.toml similarity index 100% rename from server/configuration/base.toml rename to config/base.toml diff --git a/server/configuration/local.toml b/config/local.toml similarity index 100% rename from server/configuration/local.toml rename to config/local.toml diff --git a/server/configuration/productionn.toml b/config/productionn.toml similarity index 100% rename from server/configuration/productionn.toml rename to config/productionn.toml diff --git a/server/src/lib.rs b/server/src/lib.rs index 92000fa..9079ef9 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -1,4 +1,4 @@ -mod configuration; -mod routes; -mod startup; -mod telemetry; +pub mod configuration; +pub mod routes; +pub mod startup; +pub mod telemetry; diff --git a/server/src/main.rs b/server/src/main.rs index 15956d9..b49f3fb 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -1,30 +1,16 @@ -use app::*; -use axum::Router; -use leptos::logging::log; -use leptos::prelude::*; -use leptos_axum::{LeptosRoutes, generate_route_list}; +use server::{ + configuration::get_config, + startup::Application, + telemetry::{get_subscriber, init_subscriber}, +}; +use std::io::Error; #[tokio::main] -async fn main() { - let conf = get_configuration(None).unwrap(); - let addr = conf.leptos_options.site_addr; - let leptos_options = conf.leptos_options; - // Generate the list of routes in your Leptos App - let routes = generate_route_list(App); - - let app = Router::new() - .leptos_routes(&leptos_options, routes, { - let leptos_options = leptos_options.clone(); - move || shell(leptos_options.clone()) - }) - .fallback(leptos_axum::file_and_error_handler(shell)) - .with_state(leptos_options); - - // run our app with hyper - // `axum::Server` is a re-export of `hyper::Server` - log!("listening on http://{}", &addr); - let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); - axum::serve(listener, app.into_make_service()) - .await - .unwrap(); +async fn main() -> Result<(), Error> { + let subscriber = get_subscriber("kristofersxyz", "info", std::io::stdout); + init_subscriber(subscriber); + let config = get_config().expect("Failed to read configuation."); + let application = Application::build(&config).await?; + application.start().await?; + Ok(()) } diff --git a/server/src/routes/mod.rs b/server/src/routes/mod.rs index 2ba3634..225bfca 100644 --- a/server/src/routes/mod.rs +++ b/server/src/routes/mod.rs @@ -1,6 +1,27 @@ use crate::startup::AppState; -use axum::Router; +use app::{App, shell}; +use axum::{Router, extract::State, http::StatusCode, response::IntoResponse, routing::get}; +use leptos_axum::{LeptosRoutes, generate_route_list}; pub fn route(state: AppState) -> Router { - todo!() + let leptos_options = state.leptos_options.clone(); + let routes = generate_route_list(App); + + let leptos_router = Router::new() + .leptos_routes(&leptos_options, routes, { + let leptos_options = leptos_options.clone(); + move || shell(leptos_options.clone()) + }) + .fallback(leptos_axum::file_and_error_handler(shell)) + .with_state(leptos_options); + + let api_router = Router::new() + .route("/health_check", get(health_check)) + .with_state(state); + + leptos_router.merge(api_router) +} + +async fn health_check(State(_state): State) -> impl IntoResponse { + StatusCode::OK } diff --git a/server/src/startup.rs b/server/src/startup.rs index a91f00c..a87cbac 100644 --- a/server/src/startup.rs +++ b/server/src/startup.rs @@ -2,9 +2,12 @@ use crate::{ configuration::{DatabaseSettings, Settings}, routes::route, }; +use leptos::config::{LeptosOptions, get_configuration}; use sqlx::{PgPool, postgres::PgPoolOptions}; use std::{ io::{Error, ErrorKind}, + net::SocketAddr, + ops::Deref, sync::Arc, }; use tokio::{net::TcpListener, task::JoinHandle}; @@ -13,6 +16,8 @@ use tracing::{error, info}; /// Shared application state. pub struct App { pub pool: PgPool, + pub leptos_options: LeptosOptions, + pub addr: SocketAddr, } /// Type alias for the shared application state wrapped in `Arc`. @@ -20,7 +25,6 @@ pub type AppState = Arc; /// Represents the application, including its server and configuration. pub struct Application { - port: u16, server: Option>>, } @@ -30,20 +34,25 @@ impl Application { /// This method initializes the database connection pool, binds the server /// to the specified address, and prepares the application for startup. pub async fn build(config: &Settings) -> Result { + let conf = get_configuration(None).unwrap(); + let addr = conf.leptos_options.site_addr; + let leptos_options = conf.leptos_options; + // Initialize the database connection pool let pool = get_connection_pool(&config.database); info!("Database connection pool initialized."); - // Bind the server to the specified address - let addr = format!("{}:{}", config.application.host, config.application.port); - let listener = TcpListener::bind(addr).await?; - let port = listener.local_addr().unwrap().port(); - info!("Server listening on port {}", port); - // Create the shared application state - let app_state = App { pool }.into(); + let app_state = App { + pool, + leptos_options: leptos_options.clone(), + addr, + } + .into(); // Spawn the server + info!("listening on http://{}", &addr); + let listener = TcpListener::bind(addr).await?; let server = tokio::spawn(async move { axum::serve(listener, route(app_state)).await.map_err(|e| { error!("Server error: {}", e); @@ -52,16 +61,10 @@ impl Application { }); Ok(Self { - port, server: Some(server), }) } - /// Get the port the server is listening on. - pub fn port(&self) -> u16 { - self.port - } - pub async fn start(self) -> Result<(), Error> { self.server .ok_or_else(|| Error::new(ErrorKind::Other, "Server was not initialized."))? @@ -75,3 +78,10 @@ impl Application { fn get_connection_pool(config: &DatabaseSettings) -> PgPool { PgPoolOptions::new().connect_lazy_with(config.with_db()) } + +impl Deref for App { + type Target = LeptosOptions; + fn deref(&self) -> &Self::Target { + &self.leptos_options + } +}