写在前面
Actix-web提供各种原语来使用 Rust 构建 Web 服务器和应用程序。它提供路由、中间件、请求的预处理、响应的后处理等。
1. 构建第一个Actix服务器
1.1 APP实例
所有actix-web
服务器都围绕实例构建App。它可以注册实例资源和中间件,此外还可以储存同一处理函数(handler)在同一范围内的状态(States)
#[actix_web::main]
async fn main() -> std::io::Result<()> {
//状态:应用程序状态与同一范围内的所有路由和资源共享。可以使用web::Data<T>提取器访问状态,其中`T`是状态的类型。
let share_data = web::Data::new(AppState{
status:String::from("I am Ok!"),
count:Mutex::new(0)
});
let app = move || {
App::new()
.app_data(share_data.clone())
.configure(health_check)
};
HttpServer::new(app).bind("127.0.0.1:3000")?.run().await
}
1.2 请求处理程序
Actix的请求处理程序使用接受零个或多个参数的异步(async)函数,如:
pub fn health_check(config: &mut web::ServiceConfig){
config.route("/health",web::get().to(health_handler));
}
1.3 路由守卫
路由守卫:actix-web提供guard函数,通过指定host,可用以过滤求标头信息、虚拟主机。
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(
web::scope("/")
.guard(guard::Host("www.rust-lang.org"))
.route("", web::to(|| async { HttpResponse::Ok().body("www") })),
)
.service(
web::scope("/")
.guard(guard::Host("users.rust-lang.org"))
.route("", web::to(|| async { HttpResponse::Ok().body("user") })),
)
.route("/", web::to(HttpResponse::Ok))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
2. 案例Demo
2.1 模块
- APP:初始化server实例
- Handler:路由处理函数程序
- Route:路由与中间件模块
- State:存储状态
2.2 APP
use std::sync::Mutex;
use actix_web::{web, App, HttpServer};
//声明各模块路径
#[path = "../state.rs"]
mod state;
#[path = "../route.rs"]
mod route;
#[path = "../handler.rs"]
mod handler;
use state::AppState;
use route::*;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let share_data = web::Data::new(AppState{
status:String::from("I am Ok!"),
count:Mutex::new(0)
});
let app = move || {
App::new()
.app_data(share_data.clone())
.configure(health_check) //健康检查
.configure(scoped_config) //test scope
//web::scope("/api")为配置生命统一的请求前缀
.server(web::scope("/api").configure(net_config)
};
HttpServer::new(app).bind("127.0.0.1:3000")?.run().await
}
2.3 Handler
use actix_web::{HttpResponse, web};
use super::state::AppState;
pub async fn health_handler(
app_state: web::Data<AppState>
) -> HttpResponse{
let status = &app_state.status;
let mut count = app_state.count.lock().unwrap();
let response = format!("{},{}次",status,count);
*count += 1;
HttpResponse::Ok().json(&response)
}
2.4 State
statek存储一系列的状态,可通过app_data的web::Data
use std::sync::Mutex;
pub struct AppState{
pub status:String,
pub count:Mutex<u32>
}
2.5 Configure
可模块化路由,状态,处理函数的集合,提高重用性。
/*route.rs*/
pub fn scoped_config(cfg: &mut web::ServiceConfig) {
cfg.service(
web::resource("/test")
.route(web::get().to(|| async { HttpResponse::Ok().body("test") }))
.route(web::head().to(HttpResponse::MethodNotAllowed)),
);
}
pub fn net_config(cfg: &mut web::ServiceConfig) {
cfg.service(
web::resource("/app")
.route(web::get().to(|| async { HttpResponse::Ok().body("app") }))
.route(web::head().to(HttpResponse::MethodNotAllowed)),
);
}
2.6 Route&Guard
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(
web::scope("/")
.guard(guard::Host("www.rust-lang.org"))
.route("", web::to(|| async { HttpResponse::Ok().body("www") })),
)
.service(
web::scope("/")
.guard(guard::Host("users.rust-lang.org"))
.route("", web::to(|| async { HttpResponse::Ok().body("user") })),
)
.route("/", web::to(HttpResponse::Ok))
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
3. 写在最后
参考:Actix官方文档、项目Github地址:ActixDemo
本文由 yuin 创作,
本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名。