mirror of
https://github.com/LeNei/axum-sqlx-template.git
synced 2026-02-13 22:56:19 +00:00
base inertia setup
This commit is contained in:
@@ -1,28 +1,22 @@
|
||||
use axum::{Router, routing::get};
|
||||
use http::{Method, StatusCode};
|
||||
use sqlx::PgPool;
|
||||
use tower_http::cors::{Any, CorsLayer};
|
||||
use tower_http::trace::TraceLayer;
|
||||
|
||||
use crate::config::ApiContext;
|
||||
|
||||
#[tracing::instrument(name = "Ping")]
|
||||
async fn ping() -> StatusCode {
|
||||
StatusCode::OK
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ApiContext {
|
||||
pub db: PgPool,
|
||||
}
|
||||
|
||||
pub fn build_routes(api_context: ApiContext) -> Router {
|
||||
pub fn routes(api_context: ApiContext) -> Router {
|
||||
let cors = CorsLayer::new()
|
||||
// allow `GET` and `POST` when accessing the resource
|
||||
.allow_methods([Method::GET, Method::POST])
|
||||
// allow requests from any origin
|
||||
.allow_origin(Any);
|
||||
Router::new()
|
||||
.route("/", get(ping))
|
||||
.layer(TraceLayer::new_for_http())
|
||||
.route("/ping", get(ping))
|
||||
.layer(cors)
|
||||
.with_state(api_context)
|
||||
}
|
||||
17
src/config/inertia.rs
Normal file
17
src/config/inertia.rs
Normal file
@@ -0,0 +1,17 @@
|
||||
use axum_inertia::{InertiaConfig, vite};
|
||||
|
||||
pub fn get_inertia_config(is_dev: bool) -> InertiaConfig {
|
||||
if !is_dev {
|
||||
vite::Production::new("frontend/dist/.vite/manifest.json", "src/main.tsx")
|
||||
.unwrap()
|
||||
.lang("de")
|
||||
.into_config()
|
||||
} else {
|
||||
vite::Development::default()
|
||||
.port(5173)
|
||||
.main("src/main.tsx")
|
||||
.lang("de")
|
||||
.react() // call if using react
|
||||
.into_config()
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,20 @@
|
||||
pub mod app;
|
||||
pub mod database;
|
||||
pub mod inertia;
|
||||
pub mod logging;
|
||||
|
||||
use app::ApplicationSettings;
|
||||
use axum::extract::FromRef;
|
||||
use axum_inertia::InertiaConfig;
|
||||
use database::DatabaseSettings;
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub struct Settings {
|
||||
pub database: DatabaseSettings,
|
||||
pub application: ApplicationSettings,
|
||||
pub is_dev: bool,
|
||||
}
|
||||
|
||||
pub fn get_configuration() -> Result<Settings, config::ConfigError> {
|
||||
@@ -74,3 +79,15 @@ impl TryFrom<String> for Environment {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ApiContext {
|
||||
pub db: PgPool,
|
||||
pub inertia: InertiaConfig,
|
||||
}
|
||||
|
||||
impl FromRef<ApiContext> for InertiaConfig {
|
||||
fn from_ref(app_state: &ApiContext) -> InertiaConfig {
|
||||
app_state.inertia.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod api;
|
||||
pub mod config;
|
||||
pub mod routes;
|
||||
pub mod pages;
|
||||
pub mod startup;
|
||||
|
||||
22
src/pages/mod.rs
Normal file
22
src/pages/mod.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use axum::{Router, response::IntoResponse, routing::get};
|
||||
use axum_inertia::Inertia;
|
||||
use http::Method;
|
||||
use serde_json::json;
|
||||
use tower_http::cors::CorsLayer;
|
||||
|
||||
use crate::config::ApiContext;
|
||||
|
||||
#[tracing::instrument(name = "Home Page", skip(i))]
|
||||
async fn home(i: Inertia) -> impl IntoResponse {
|
||||
i.render("Home", json!({}))
|
||||
}
|
||||
|
||||
pub fn routes(api_context: ApiContext) -> Router {
|
||||
let cors = CorsLayer::new()
|
||||
// allow `GET` and `POST` when accessing the resource
|
||||
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE]);
|
||||
Router::new()
|
||||
.route("/", get(home))
|
||||
.layer(cors)
|
||||
.with_state(api_context)
|
||||
}
|
||||
@@ -1,21 +1,49 @@
|
||||
use crate::config::Settings;
|
||||
use crate::routes::{build_routes, ApiContext};
|
||||
use crate::api::routes as api_routes;
|
||||
use crate::config::inertia::get_inertia_config;
|
||||
use crate::config::{ApiContext, Settings};
|
||||
use crate::pages::routes as page_routes;
|
||||
use tower_http::services::ServeDir;
|
||||
|
||||
use anyhow::Context;
|
||||
use axum::Router;
|
||||
use tokio::net::TcpListener;
|
||||
use tower_http::trace::TraceLayer;
|
||||
|
||||
pub async fn build(settings: Settings) -> anyhow::Result<()> {
|
||||
let api_context = ApiContext {
|
||||
db: settings.database.get_connection_pool(),
|
||||
inertia: get_inertia_config(settings.is_dev),
|
||||
};
|
||||
let api_router = build_routes(api_context);
|
||||
|
||||
tracing::info!("Creating router...");
|
||||
let mut router = Router::new()
|
||||
.merge(page_routes(api_context.clone()))
|
||||
.nest("/api", api_routes(api_context))
|
||||
.layer(TraceLayer::new_for_http());
|
||||
|
||||
if !settings.is_dev {
|
||||
// Serve static assets in production from the frontend/dist/assets directory instead of Vite
|
||||
let service = ServeDir::new("frontend/dist/assets").precompressed_gzip();
|
||||
router = router.nest_service("/assets", service);
|
||||
}
|
||||
|
||||
let public_service = match settings.is_dev {
|
||||
true => ServeDir::new("frontend/public"),
|
||||
false => ServeDir::new("frontend/dist"),
|
||||
};
|
||||
router = router.fallback_service(public_service);
|
||||
|
||||
let address = format!(
|
||||
"{}:{}",
|
||||
settings.application.host, settings.application.port
|
||||
);
|
||||
let listener = TcpListener::bind(address).await.context("Failed to bind to port")?;
|
||||
|
||||
run(api_router, listener).await
|
||||
tracing::info!("Binding to address: {}", address);
|
||||
let listener = TcpListener::bind(address)
|
||||
.await
|
||||
.context("Failed to bind to port")?;
|
||||
|
||||
run(router, listener).await
|
||||
}
|
||||
|
||||
async fn run(router: Router, listener: TcpListener) -> anyhow::Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user