litecloud/api/src/main.rs

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(())
}