A very performant and light (2mb in memory) link shortener and tracker. Written in Rust and React and uses Postgres/SQLite.
1use actix_cors::Cors; 2use actix_files::Files; 3use actix_web::{middleware::DefaultHeaders, web, App, HttpServer}; 4use anyhow::Result; 5use simplelink::{handlers, AppState}; 6use sqlx::postgres::PgPoolOptions; 7use tracing::info; 8 9async fn index() -> Result<actix_files::NamedFile, actix_web::Error> { 10 Ok(actix_files::NamedFile::open("./static/index.html")?) 11} 12 13#[actix_web::main] 14async fn main() -> Result<()> { 15 // Load environment variables from .env file 16 dotenv::dotenv().ok(); 17 18 // Initialize logging 19 tracing_subscriber::fmt::init(); 20 21 // Database connection string from environment 22 let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set"); 23 24 // Create database connection pool 25 let pool = PgPoolOptions::new() 26 .max_connections(5) 27 .acquire_timeout(std::time::Duration::from_secs(3)) 28 .connect(&database_url) 29 .await?; 30 31 // Run database migrations 32 sqlx::migrate!("./migrations").run(&pool).await?; 33 34 let state = AppState { db: pool }; 35 36 let host = std::env::var("SERVER_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); 37 let port = std::env::var("SERVER_PORT").unwrap_or_else(|_| "8080".to_string()); 38 info!("Starting server at http://{}:{}", host, port); 39 40 // Start HTTP server 41 HttpServer::new(move || { 42 let cors = Cors::default() 43 .allow_any_origin() 44 .allow_any_method() 45 .allow_any_header() 46 .max_age(3600); 47 48 App::new() 49 .wrap(cors) 50 .app_data(web::Data::new(state.clone())) 51 .service( 52 web::scope("/api") 53 .route("/shorten", web::post().to(handlers::create_short_url)) 54 .route("/links", web::get().to(handlers::get_all_links)) 55 .route("/links/{id}", web::delete().to(handlers::delete_link)) 56 .route("/auth/register", web::post().to(handlers::register)) 57 .route("/auth/login", web::post().to(handlers::login)) 58 .route("/health", web::get().to(handlers::health_check)), 59 ) 60 .service(web::resource("/{short_code}").route(web::get().to(handlers::redirect_to_url))) 61 }) 62 .workers(2) 63 .backlog(10_000) 64 .bind(format!("{}:{}", host, port))? 65 .run() 66 .await?; 67 68 Ok(()) 69}