Skip to content

Commit 8479839

Browse files
author
Nick Miller
committed
http(serve): move state outside of serve function, use Extension for examples due to sqlx compile time checking
1 parent ebaddea commit 8479839

File tree

4 files changed

+17
-20
lines changed

4 files changed

+17
-20
lines changed

Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ name = "demo"
2020
name = "echo"
2121

2222
[dependencies]
23-
axum = { version = "0.6.20", features = ["json"] }
23+
axum = { version = "0.6.20", features = ["json", "macros"] }
2424
clap = { version = "4", features = ["derive", "env"] }
2525
once_cell = "1.18"
2626
prometheus = "0.13"
2727
serde = { version = "1.0", features = ["derive"] }
2828
serde_json = "1.0"
2929
tokio = { version = "1.32", features = ["full"] }
3030
tower = "0.4"
31-
tower-http = { version = "0.4", features = ["cors", "trace", "map-request-body"] }
31+
tower-http = { version = "0.4", features = ["cors", "trace", "map-request-body", "util"] }
3232
tracing = "0.1"
3333
tracing-subscriber = { version = "0.3", features = ["fmt", "std", "json", "env-filter"] }
3434

examples/demo/main.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// SPDX-License-Identifier: AGPL-3.0-or-later
44

55
use servus::axum::{
6-
extract::{self, State},
6+
extract::{self, Extension},
77
http::StatusCode,
88
response::IntoResponse,
99
routing::{get, post},
@@ -25,6 +25,7 @@ struct AppConfig {
2525
response: String,
2626
}
2727

28+
#[derive(Clone)]
2829
struct AppState {
2930
pool: sqlx::postgres::PgPool,
3031
}
@@ -56,13 +57,13 @@ async fn main() -> anyhow::Result<()> {
5657

5758
let router = Router::new()
5859
.route("/message", post(post_message))
59-
.route("/message/all", get(get_messages));
60+
.route("/message/all", get(get_messages))
61+
.layer(Extension(state));
6062

6163
servus::http::serve(
6264
config.servus.http_address,
6365
Some(config.servus.metrics_address),
6466
router,
65-
state,
6667
)
6768
.await;
6869

@@ -76,7 +77,7 @@ struct Message {
7677
}
7778

7879
async fn post_message(
79-
State(state): State<Arc<AppState>>,
80+
Extension(state): Extension<Arc<AppState>>,
8081
extract::Json(payload): extract::Json<Message>,
8182
) -> StatusCode {
8283
info!(
@@ -88,7 +89,7 @@ async fn post_message(
8889
if let Err(e) = sqlx::query!(
8990
"INSERT INTO guestbook (author, message) VALUES ($1, $2)",
9091
payload.author,
91-
payload.message
92+
payload.message,
9293
)
9394
.execute(&state.pool)
9495
.await
@@ -100,7 +101,7 @@ async fn post_message(
100101
StatusCode::OK
101102
}
102103

103-
async fn get_messages(State(state): State<Arc<AppState>>) -> impl IntoResponse {
104+
async fn get_messages(Extension(state): Extension<Arc<AppState>>) -> impl IntoResponse {
104105
info!(message = "got get messages request!");
105106

106107
let q = sqlx::query!("select * from guestbook")

examples/echo/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ async fn main() -> anyhow::Result<()> {
2525
// Note, we pass the `metrics_address` parameter value as `None` to imply we don't want to
2626
// start the metrics server. Also, the `state` parameter is the unit type `()`, meaning we have
2727
// no global state and all handlers are stateless.
28-
servus::http::serve(config.servus.http_address, None, router, ()).await;
28+
servus::http::serve(config.servus.http_address, None, router).await;
2929

3030
Ok(())
3131
}

src/http/mod.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,14 @@ use tracing::{error, Level};
3232
///
3333
/// Both the application server and metrics server will respond to a CTRL-C shutdown signal and
3434
/// terminate gracefully.
35-
pub async fn serve<S>(
35+
pub async fn serve(
3636
http_address: SocketAddr,
3737
metrics_address: Option<SocketAddr>,
38-
router: Router<S>,
39-
state: S,
40-
) where
41-
S: Send + Sync + Clone + 'static,
42-
{
38+
router: Router<()>,
39+
) {
4340
// create primary application router and server
4441
// applying handler state if we have it, and default metrics/tracing middleware
45-
let r = router
46-
.with_state(state)
42+
let router = router
4743
.route_layer(middleware::from_fn(metrics::middleware)) // only record matched routes
4844
.layer(
4945
TraceLayer::new_for_http().make_span_with(
@@ -54,17 +50,17 @@ pub async fn serve<S>(
5450
);
5551

5652
let app = Server::bind(&http_address)
57-
.serve(r.into_make_service())
53+
.serve(router.into_make_service())
5854
.with_graceful_shutdown(shutdown_signal());
5955

6056
if let Some(metrics_address) = metrics_address {
6157
// create metrics router and server, also used for healthcheck
62-
let r = Router::new()
58+
let router = Router::new()
6359
.route("/metrics", routing::get(metrics::handler))
6460
.route("/health", routing::get(health));
6561

6662
let metrics = Server::bind(&metrics_address)
67-
.serve(r.into_make_service())
63+
.serve(router.into_make_service())
6864
.with_graceful_shutdown(shutdown_signal());
6965

7066
// spawn each server instance (so they can be scheduled on separate threads as necessary)

0 commit comments

Comments
 (0)