use std::env; use anyhow::Context; use axum::extract::FromRef; use axum::http::{HeaderValue, Method}; use axum::Router; use como_infrastructure::register::ServiceRegister; use tower::ServiceBuilder; use tower_http::{cors::CorsLayer, trace::TraceLayer}; use crate::controllers::auth::AuthController; use crate::controllers::graphql::GraphQLController; pub struct Api; impl Api { pub async fn new( port: u32, cors_origin: &str, service_register: ServiceRegister, ) -> anyhow::Result<()> { let app_state = AppState { service_register: service_register.clone(), }; let router = Router::new() .nest( "/auth", AuthController::new_router(service_register.clone(), app_state.clone()).await?, ) .nest( "/graphql", GraphQLController::new_router(service_register.clone(), app_state.clone()), ) .layer( ServiceBuilder::new() .layer(TraceLayer::new_for_http()) .layer( CorsLayer::new() .allow_origin( cors_origin .parse::() .context("could not parse cors origin as header")?, ) .allow_headers([axum::http::header::CONTENT_TYPE]) .allow_methods([Method::GET, Method::POST, Method::OPTIONS]) .allow_credentials(true), ), ); let host = env::var("HOST").unwrap_or("0.0.0.0".to_string()); tracing::info!("running on: {host}:{}", port); axum::Server::bind(&format!("{host}:{}", port).parse().unwrap()) .serve(router.into_make_service()) .await .context("error while starting API")?; Ok(()) } } #[derive(Clone)] pub struct AppState { service_register: ServiceRegister, } impl FromRef for ServiceRegister { fn from_ref(input: &AppState) -> Self { input.service_register.clone() } }