Rust Actix Web框架初试
   笔记Rust基础    0 comment
Rust Actix Web框架初试
   笔记Rust基础    0 comment

写在前面

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 模块

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注册到App实例,

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

Responses