starchart/src/main.rs

101 lines
3.5 KiB
Rust

use aide::{axum::ApiRouter, openapi::OpenApi};
use axum::{extract::DefaultBodyLimit, Extension};
use hyper::{
header::{ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_LENGTH, DATE, SET_COOKIE, VARY},
Method,
};
use std::{
net::{Ipv4Addr, SocketAddr},
sync::Arc,
time::Duration,
};
use tower_http::{compression::CompressionLayer, cors::CorsLayer, timeout::TimeoutLayer};
use tracing::info;
use tracing_subscriber::fmt::SubscriberBuilder;
pub mod config;
pub mod db;
pub mod docs;
pub mod extractors;
mod frontend;
pub mod stars;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
SubscriberBuilder::default().pretty().init();
info!("running migrations! please wait...");
sqlx::migrate!("./migrations").run(db::pool().await).await?;
info!("migrations done! 😎");
start_server().await?;
Ok(())
}
async fn generate_server() -> Result<axum::Router, Box<dyn std::error::Error>> {
aide::gen::on_error(|error| panic!("{}", error));
aide::gen::extract_schemas(true);
let mut open_api = OpenApi::default();
aide::gen::on_error(|error| panic!("{}", error));
Ok(ApiRouter::new()
.nest_api_service("/api/v1/stars", stars::routes())
.nest_api_service("/docs", docs::routes())
.nest_api_service("/", frontend::routes())
.finish_api_with(&mut open_api, |docs| {
docs.title("starchart")
.summary("now you can discover a star!")
.description("disclaimer: this website is still in beta! your stars might change at any point!")
.contact(aide::openapi::Contact {
name: Some("zoe".into()),
url: Some("https://zoe.kittycat.homes".into()),
..Default::default()
})
.version("0.1.0")
})
.layer(Extension(Arc::new(open_api)))
.layer(TimeoutLayer::new(Duration::from_secs(60)))
.layer(DefaultBodyLimit::max(2000))
.layer(
CorsLayer::new()
.allow_methods([Method::POST, Method::GET, Method::PUT, Method::PATCH])
.allow_origin([
#[cfg(debug_assertions)]
"localhost".parse()?,
#[cfg(debug_assertions)]
"http://localhost:8080".parse()?,
#[cfg(debug_assertions)]
"http://127.0.0.1:8080".parse()?,
crate::config::CONFIG.server_url.parse()?,
])
.allow_headers([
ACCESS_CONTROL_ALLOW_ORIGIN,
SET_COOKIE,
VARY,
DATE,
CONTENT_LENGTH,
])
.expose_headers([
ACCESS_CONTROL_ALLOW_ORIGIN,
SET_COOKIE,
VARY,
DATE,
CONTENT_LENGTH,
])
.allow_credentials(true),
)
.layer(
CompressionLayer::new()
.gzip(true)
// we have as much cpu as we want really
// since rust is kinda overkill anyway
.quality(tower_http::CompressionLevel::Best),
))
}
async fn start_server() -> Result<(), Box<dyn std::error::Error>> {
let app = generate_server().await?;
let addr = SocketAddr::new(std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 7056);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await?;
Ok(())
}