94 lines
2.8 KiB
Rust
94 lines
2.8 KiB
Rust
use axum::{
|
|
error_handling::HandleErrorLayer,
|
|
extract::Extension,
|
|
http::{HeaderValue, Method, StatusCode},
|
|
routing::get,
|
|
Router,
|
|
};
|
|
use dotenvy::dotenv;
|
|
use sqlx::postgres::PgPoolOptions;
|
|
use std::{env, net::SocketAddr, path::PathBuf, sync::Arc, time::Duration};
|
|
use tower::ServiceBuilder;
|
|
use tower_http::{cors::CorsLayer, services::ServeDir, trace::TraceLayer};
|
|
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
|
|
|
mod config;
|
|
mod error;
|
|
mod models;
|
|
mod routes;
|
|
mod services;
|
|
mod utils;
|
|
|
|
use config::Config;
|
|
use error::AppError;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
dotenv().ok();
|
|
|
|
tracing_subscriber::registry()
|
|
.with(tracing_subscriber::EnvFilter::new(
|
|
env::var("RUST_LOG").unwrap_or_else(|_| "info,tower_http=debug".into()),
|
|
))
|
|
.with(tracing_subscriber::fmt::layer())
|
|
.init();
|
|
|
|
let config = Config::from_env();
|
|
let config = Arc::new(config);
|
|
|
|
let storage_path = PathBuf::from(&config.storage_path);
|
|
if !storage_path.exists() {
|
|
std::fs::create_dir_all(&storage_path)?;
|
|
}
|
|
|
|
let pool = PgPoolOptions::new()
|
|
.max_connections(10)
|
|
.connect(&config.database_url)
|
|
.await?
|
|
|
|
sqlx::migrate!("./migrations")
|
|
.run(&pool)
|
|
.await?
|
|
|
|
tracing::info!("Database migrations applied successfully");
|
|
|
|
let encryption_service = services::encryption::EncryptionService::new(&config.master_key);
|
|
|
|
let cors = CorsLayer::new()
|
|
.allow_origin("*".parse::<HeaderValue>().unwrap())
|
|
.allow_methods([Method::GET, Method::POST, Method::PUT, Method::DELETE])
|
|
.allow_headers([axum::http::header::CONTENT_TYPE, axum::http::header::AUTHORIZATION]);
|
|
|
|
let api_router = Router::new()
|
|
.nest("/api", routes::api_routes())
|
|
.layer(
|
|
ServiceBuilder::new()
|
|
.layer(HandleErrorLayer::new(|error| async move {
|
|
(
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
format!("Unhandled error: {}", error),
|
|
)
|
|
}))
|
|
.layer(TraceLayer::new_for_http())
|
|
.layer(Extension(pool.clone()))
|
|
.layer(Extension(Arc::clone(&config)))
|
|
.layer(Extension(encryption_service)),
|
|
);
|
|
|
|
let static_files_service = ServeDir::new("static");
|
|
let static_router = Router::new().nest_service("/", static_files_service.clone());
|
|
|
|
let app = Router::new()
|
|
.merge(api_router)
|
|
.fallback_service(static_router)
|
|
.layer(cors);
|
|
|
|
let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
|
|
tracing::info!("Listening on {}", addr);
|
|
|
|
axum::Server::bind(&addr)
|
|
.serve(app.into_make_service())
|
|
.await?
|
|
|
|
Ok(())
|
|
} |