-
Notifications
You must be signed in to change notification settings - Fork 0
/
startup.rs
82 lines (68 loc) · 2.4 KB
/
startup.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use std::net::SocketAddr;
use axum::{routing::get, Extension, Router};
use sqlx::{postgres::PgPoolOptions, PgPool};
use tokio::net::TcpListener;
use tower::ServiceBuilder;
use tower_http::{
request_id::MakeRequestUuid,
trace::{DefaultMakeSpan, DefaultOnFailure, DefaultOnResponse, TraceLayer},
LatencyUnit, ServiceBuilderExt,
};
use tracing::Level;
use crate::{
handlers,
settings::{DatabaseSettings, Settings},
};
pub struct Application {
app: Router,
listener: TcpListener,
}
impl Application {
pub async fn build(settings: Settings) -> Result<Self, std::io::Error> {
let connection_pool = get_connection_pool(&settings.database);
let address = format!(
"{}:{}",
settings.application.host, settings.application.port
);
let listener = TcpListener::bind(address).await?;
let tracing_layer = TraceLayer::new_for_http()
.make_span_with(
DefaultMakeSpan::new()
.level(Level::INFO)
.include_headers(true),
)
.on_response(
DefaultOnResponse::new()
.include_headers(true)
.level(Level::INFO)
.latency_unit(LatencyUnit::Millis),
)
.on_failure(DefaultOnFailure::new().level(Level::ERROR));
let middleware = ServiceBuilder::new()
.set_x_request_id(MakeRequestUuid)
.layer(tracing_layer)
.propagate_x_request_id();
let app = Router::new()
.route("/_health-check", get(handlers::health_check_handler))
.nest("/auth", handlers::auth_router())
.layer(middleware)
.layer(Extension(connection_pool));
Ok(Self { app, listener })
}
pub fn address(&self) -> Result<SocketAddr, std::io::Error> {
self.listener.local_addr()
}
pub async fn run_until_stopped(self) -> Result<(), std::io::Error> {
tracing::debug!("Listening on {}", self.listener.local_addr().unwrap());
axum::serve(
self.listener,
self.app.into_make_service_with_connect_info::<SocketAddr>(),
)
.await
}
}
pub fn get_connection_pool(settings: &DatabaseSettings) -> PgPool {
PgPoolOptions::new()
.acquire_timeout(std::time::Duration::from_secs(2))
.connect_lazy_with(settings.with_database())
}