typestar

Shared state in Rust

State carries a handle to whatever your handlers share — a pool, a cache, a counter.

use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;

use axum::extract::State;
use axum::{routing::get, Router};

#[derive(Clone)]
struct AppState {
    hits: Arc<AtomicU64>,
}

async fn count(State(state): State<AppState>) -> String {
    let n = state.hits.fetch_add(1, Ordering::Relaxed) + 1;
    format!("{n} requests so far")
}

#[tokio::main]
async fn main() {
    let state = AppState { hits: Arc::new(AtomicU64::new(0)) };
    let app = Router::new().route("/count", get(count)).with_state(state);

    let listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
        .await
        .unwrap();
    axum::serve(listener, app).await.unwrap();
}

How it works

  1. with_state attaches it to the router.
  2. State<T> extracts it in each handler.
  3. The value is cloned per request, so wrap it in an Arc.

Keywords and builtins used here

The run, in numbers

Lines
26
Characters to type
626
Tokens
189
Three-star pace
110 tpm

At the three-star pace of 110 tokens a minute, this run takes about 103 seconds.

Type this snippet

Step 2 of 2 in Extractors & state, step 5 of 9 in Web services with axum.

← Previous Next →