App state in Actix-web

Understanding App State
This Actix-Web Rust server handles messages and tracks server status. It shares state using Mutex
-protected HashMap
and String
. Clients can GET
or POST
a message and GET
a list of servers. State is initialized in main
and injected into request handlers for simple thread-safe access.
use actix_web::{App, HttpResponse, HttpServer, web};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Mutex;
#[derive(Serialize, Deserialize)]
struct Message {
content: String,
}
#[derive(Serialize, Clone)]
struct Server {
name: String,
status: String,
}
// shared application state
struct AppState {
// Use a regular Mutex for simplicity
servers: Mutex<HashMap<String, Server>>,
// For a simple version, we'll just keep the last message
last_message: Mutex<String>,
}
// Handle GET requests to /message
async fn get_message(data: web::Data<AppState>) -> HttpResponse {
let message = data.last_message.lock().unwrap().clone();
HttpResponse::Ok().json(Message { content: message })
}
// Handle POST requests to /message
async fn post_message(msg: web::Json<Message>, data: web::Data<AppState>) -> HttpResponse {
// Store the message
let mut last_message = data.last_message.lock().unwrap();
*last_message = msg.content.clone();
// Return success response
HttpResponse::Ok().body("Message received")
}
// List all servers
async fn list_servers(data: web::Data<AppState>) -> HttpResponse {
let servers = data.servers.lock().unwrap();
let server_list: Vec<_> = servers.values().cloned().collect();
HttpResponse::Ok().json(server_list)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
println!("Starting simple message server...");
// Initialize our state
let mut server_map = HashMap::new();
server_map.insert(
"server1".to_string(),
Server {
name: "Demo Server".to_string(),
status: "Online".to_string(),
},
);
let state = web::Data::new(AppState {
servers: Mutex::new(server_map),
last_message: Mutex::new("No messages yet".to_string()),
});
HttpServer::new(move || {
App::new()
.app_data(state.clone())
.route("/message", web::get().to(get_message))
.route("/message", web::post().to(post_message))
.route("/servers", web::get().to(list_servers))
})
.bind("127.0.0.1:8000")?
.run()
.await
}