如何将Actix-Web应用的状态管理为?

摘要:一、概述 Actix Web 提供了强大的应用状态管理机制,让你能够在整个应用范围内安全地共享数据。 ‌核心状态管理方式‌: 应用状态会被同一作用域内的所有路由和资源共享,可以通过 web::Data<T&am
一、概述 Actix Web 提供了强大的应用状态管理机制,让你能够在整个应用范围内安全地共享数据。 ‌核心状态管理方式‌: 应用状态会被同一作用域内的所有路由和资源共享,可以通过 web::Data<T> 提取器来访问,其中 T 代表状态数据的类型。 二、共享状态(App Data) 修改主代码 src/main.rs use actix_web::{web,get,post, App, HttpResponse, HttpServer}; use std::sync::Mutex; struct AppState { counter: Mutex<i32>, app_name: String, } #[get("/count")] async fn get_count(data: web::Data<AppState>) -> HttpResponse { let count = data.counter.lock().unwrap(); HttpResponse::Ok().json(serde_json::json!({ "app": data.app_name, "count": *count })) } #[post("/increment")] async fn increment(data: web::Data<AppState>) -> HttpResponse { let mut count = data.counter.lock().unwrap(); *count += 1; HttpResponse::Ok().json(serde_json::json!({ "new_count": *count })) } #[actix_web::main] async fn main() -> std::io::Result<()> { env_logger::init_from_env(env_logger::Env::default().default_filter_or("info")); log::info!("Starting HTTP server on http://127.0.0.1:8080"); let app_state = web::Data::new(AppState { counter: Mutex::new(0), app_name: String::from("Actix-Web Demo"), }); HttpServer::new(move || { App::new() .app_data(app_state.clone()) .service(get_count) .service(increment) }) .bind(("127.0.0.1", 8080))? .run() .await } 测试运行,访问接口:http://127.0.0.1:8080/count 使用postman调用post接口:http://127.0.0.1:8080/increment 三、数据库连接池 这里以mysql 8为例,来演示如何连接数据库。 数据库在阿里云上面,创建一个测试数据库 CREATE DATABASE rust_blog CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 新建表users CREATE TABLE `users` ( `id` bigint NOT NULL AUTO_INCREMENT, `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL, `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL, `create_time` datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; 插入2条数据 INSERT INTO `rust_blog`.`users` (`id`, `username`, `password`, `email`, `create_time`) VALUES (1, 'Alice', 'e10adc3949ba59abbe56e057f20f883e', 'alice@example.com', '2025-11-26 18:24:22'); INSERT INTO `rust_blog`.`users` (`id`, `username`, `password`, `email`, `create_time`) VALUES (2, 'Bob', 'e10adc3949ba59abbe56e057f20f883e', 'bob@example.com', '2025-11-26 18:25:45'); 注意:密码使用md5加密 修改Cargo.toml,增加mysql模块 # 异步 MySQL 驱动,支持 8.x sqlx = { version = "0.8", features = ["runtime-tokio-native-tls", "mysql"] } dotenvy = "0.15" # 读取 .env 项目根目录,新增文件.env DATABASE_URL=mysql://root:123456@localhost:3306/rust_blog 注意:如果密码带有@符号,需要进行URL-encode编码 打开在线url编码器,链接:https://www.convertstring.com/zh_CN/EncodeDecode/UrlEncode 修改主代码 src/main.rs use actix_web::{web, App, HttpResponse, HttpServer}; use dotenvy::dotenv; use sqlx::{mysql::MySqlPool, mysql::MySqlPoolOptions, FromRow}; use serde::Serialize; #[derive(FromRow, Serialize)] struct User { id: i64, // MySQL 里 BIGINT 对应 i64 username: String, email: String, } #[actix_web::get("/users")] async fn get_users_from_db(pool: web::Data<MySqlPool>) -> HttpResponse { let users = sqlx::query_as::<_, User>("SELECT id, username, email FROM users") .fetch_all(pool.get_ref()) .await; match users { Ok(users) => HttpResponse::Ok().json(users), Err(e) => HttpResponse::InternalServerError().json(serde_json::json!({ "error": e.to_string() })), } } #[actix_web::main] async fn main() -> std::io::Result<()> { dotenv().ok(); env_logger::init_from_env(env_logger::Env::default().default_filter_or("info")); // 建立连接池 let db_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set"); let pool = MySqlPoolOptions::new() .max_connections(5) .connect(&db_url) .await .expect("Failed to create MySqlPool"); HttpServer::new(move || { App::new() .app_data(web::Data::new(pool.clone())) .service(get_users_from_db) }) .bind(("127.0.0.1", 8080))? .run() .await } 注意:这里设置的连接池大小为5,生产环境,请根据实际情况修改。 重新运行,访问:http://127.0.0.1:8080/users 显示2条用户信息 本文参考链接:https://blog.csdn.net/sinat_41617212/article/details/154069236