service boilerplate

db-work
Patrick Cleavelin 2025-11-04 15:59:00 -06:00
parent ba0932b511
commit 8637bf1b53
12 changed files with 933 additions and 3 deletions

839
service/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -8,12 +8,13 @@ path = "src/main.rs"
[lib] [lib]
name = "a_ci_lib" name = "a_ci_lib"
path = "src/lib.rs" path = "src/lib/mod.rs"
[dependencies] [dependencies]
anyhow = "1.0.100" anyhow = "1.0.100"
axum = { version = "0.6.9", features = ["headers"] } axum = { version = "0.6.9", features = ["headers"] }
dotenv = "0.15.0" dotenv = "0.15.0"
reqwest = "0.11.14"
serde = "1.0.152" serde = "1.0.152"
serde_json = "1.0.93" serde_json = "1.0.93"
thiserror = "1.0.38" thiserror = "1.0.38"

View File

View File

@ -0,0 +1 @@
pub mod ci;

View File

@ -0,0 +1,4 @@
pub mod interface;
mod base_service;
pub use base_service::Service as BaseService;

View File

@ -0,0 +1,6 @@
use super::interface::CiService;
#[derive(Clone)]
pub struct Service {}
impl CiService for Service {}

View File

@ -0,0 +1 @@
pub trait CiService: Send + Sync + Clone + 'static {}

View File

@ -0,0 +1 @@
pub mod http;

View File

@ -0,0 +1,65 @@
mod handlers;
use std::{net::SocketAddr, sync::Arc};
use axum::{
routing::{get, post},
};
use tower_http::cors::CorsLayer;
use reqwest::Method;
use crate::{
domain::ci::interface::CiService,
};
#[derive(Clone)]
pub(crate) struct ApiState<S>
where
S: CiService,
{
ci_service: Arc<S>,
}
pub struct HttpServer {
make_service: axum::routing::IntoMakeService<axum::Router>,
}
impl HttpServer {
pub fn new(
ci_service: impl CiService,
) -> anyhow::Result<Self> {
let state = ApiState {
ci_service: Arc::new(ci_service),
};
let router = routes()
.layer(
CorsLayer::new()
.allow_headers(tower_http::cors::Any)
.allow_methods([Method::GET, Method::POST, Method::DELETE]),
)
.with_state(state);
Ok(Self {
make_service: router.into_make_service(),
})
}
pub async fn run(self) {
let addr = SocketAddr::from(([0, 0, 0, 0], 8100));
eprintln!("socket listening on {addr}");
axum::Server::bind(&addr)
.serve(self.make_service)
.await
.expect("couldn't start http server");
}
}
fn routes<S>() -> axum::Router<ApiState<S>>
where
S: CiService,
{
axum::Router::<ApiState<S>>::new()
.route("/health", get(handlers::health))
}

View File

@ -0,0 +1,3 @@
pub(super) async fn health() -> String {
"OK".to_string()
}

2
service/src/lib/mod.rs Normal file
View File

@ -0,0 +1,2 @@
pub mod domain;
pub mod inbound;

View File

@ -1,3 +1,10 @@
fn main() { use a_ci_lib::{inbound, domain::ci::BaseService};
println!("Hello, world!");
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let http_server = inbound::http::HttpServer::new(BaseService {})?;
http_server.run().await;
Ok(())
} }