BotTerre/libs/api/src/lib.rs
2025-06-04 01:25:39 +02:00

62 lines
2.1 KiB
Rust

use actix_cors::Cors;
use actix_web::{dev::Service, http::header, App, HttpServer};
use apidocs::ApiDocs;
use clickhouse_pool::pool_manager::PoolManager;
use config::Config;
use poise::serenity_prelude::Http;
use std::{net::Ipv4Addr, sync::Arc};
use tracing::{error, info};
use tracing_actix_web::{RequestId, TracingLogger};
use utoipa::OpenApi;
use utoipa_actix_web::AppExt;
use utoipa_scalar::{Scalar, Servable as ScalarServable};
pub mod apidocs;
pub async fn init_api(config: Config, pool: Arc<PoolManager>, http: Arc<Http>) -> Result<(), ()> {
let port = config.port;
HttpServer::new(move || {
let cors = Cors::default()
.allow_any_origin()
.allow_any_method()
.allow_any_header()
.max_age(3600);
App::new()
.wrap(cors)
.wrap_fn(|mut req, srv| {
let request_id_asc = req.extract::<RequestId>();
let fut = srv.call(req);
async move {
let mut res = fut.await?;
let request_id: RequestId = request_id_asc.await.unwrap();
let request_id_str = format!("{}", request_id);
let headers = res.headers_mut();
headers.insert(
header::HeaderName::from_static("x-request-id"),
header::HeaderValue::from_str(request_id_str.as_str()).unwrap(),
);
Ok(res)
}
})
.wrap(TracingLogger::default())
.into_utoipa_app()
.openapi(ApiDocs::openapi())
.app_data(actix_web::web::Data::new(pool.clone()))
.app_data(actix_web::web::Data::new(http.clone()))
.app_data(actix_web::web::Data::new(config.clone()))
.openapi_service(|api| Scalar::with_url("/api/docs", api))
.into_app()
})
.bind((Ipv4Addr::UNSPECIFIED, port))
.map_err(|e| {
error!("Failed to bind API server: {}", e);
})?
.run()
.await
.map_err(|e| {
eprintln!("Failed to start API server: {}", e);
})?;
info!("Api server stopped");
Ok(())
}