当前位置:   article > 正文

Rust Web开发框架actix-web入门案例

Rust Web开发框架actix-web入门案例

概述

在看书的时候,用到了actix-web这个框架的案例。

书里面的版本是1.0,但是我看官网最新都4.4了。

为了抹平这种信息差,所以我决定把官方提供的示例代码过一遍。

核心代码

Cargo.toml

[package]
name = "hello"
version = "0.1.0"
edition = "2021"

[dependencies]
actix-web = "4.4"
env_logger = "0.11"
log = "0.4"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

main.rs

use actix_web::{middleware, web, App, HttpRequest, HttpServer};

async fn index(req: HttpRequest) -> &'static str {
    println!("REQ: {req:?}");
    "Hello world!"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
    log::info!("starting HTTP server at http://192.168.77.129:8000");
    
    let server = HttpServer::new(|| {
        App::new()
            .wrap(middleware::Logger::default())
            .service(web::resource("/index.html").to(|| async {"Hello html!"}))
            .service(web::resource("/").to(index))
    });
    server.bind("0.0.0.0:8000")?
        .run()
        .await
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

运行和访问

http://192.168.77.129:8000/
在这里插入图片描述

http://192.168.77.129:8000/index.html
在这里插入图片描述

代码解读

引入依赖:

use actix_web::{middleware, web, App, HttpRequest, HttpServer};
  • 1

首页路由:

  • 获取请求信息:index(req: HttpRequest)
  • 返回一个纯文本字符串:&'static str
async fn index(req: HttpRequest) -> &'static str {
    println!("REQ: {req:?}");
    "Hello world!"
}
  • 1
  • 2
  • 3
  • 4

入口方法:

  • 定义入口方法:#[actix_web::main]
  • 声明入口方法:async fn main() -> std::io::Result<()> {
  • 初始化日志:env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
  • 记录一个info级别的日志:log::info!("starting HTTP server at http://192.168.77.129:8000");
  • 创建服务对象:let server = HttpServer::new(|| {
  • 使用日志中间件:.wrap(middleware::Logger::default())
  • 挂载路由/index.html.service(web::resource("/index.html").to(|| async {"Hello html!"}))
  • 挂载路由/ .service(web::resource("/").to(index))
  • 启动服务:server.bind("0.0.0.0:8000")?
#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
    log::info!("starting HTTP server at http://192.168.77.129:8000");
    
    let server = HttpServer::new(|| {
        App::new()
            .wrap(middleware::Logger::default())
            .service(web::resource("/index.html").to(|| async {"Hello html!"}))
            .service(web::resource("/").to(index))
    });
    server.bind("0.0.0.0:8000")?
        .run()
        .await
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

测试代码

actix-web框架还支持对web进行测试。

核心代码如下:

  • 创建应用对象:let app = App::new().route("/", web::get().to(index));
  • 设置测试对象:let app = test::init_service(app).await;
  • 构造请求对象:let req = test::TestRequest::get().uri("/").to_request();
  • 发送请求,获取响应:let resp = app.call(req).await?;
  • 断言响应状态码:assert_eq!(resp.status(), http::StatusCode::OK);
  • 获取响应体内容:let response_body = resp.into_body();
  • 断言响应体内容:assert_eq!(to_bytes(response_body).await?, r##"Hello world!"##);
#[cfg(test)]
mod tests {
    use actix_web::{body::to_bytes, dev::Service, http, test, Error};
    use super::*;

    #[actix_web::test]
    async fn test_index() -> Result<(), Error> {
        let app = App::new().route("/", web::get().to(index));
        let app = test::init_service(app).await;

        let req = test::TestRequest::get().uri("/").to_request();
        let resp = app.call(req).await?;
        assert_eq!(resp.status(), http::StatusCode::OK);

        let response_body = resp.into_body();
        assert_eq!(to_bytes(response_body).await?, r##"Hello world!"##);

        Ok(())
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

完整代码:

use actix_web::{middleware, web, App, HttpRequest, HttpServer};

async fn index(req: HttpRequest) -> &'static str {
    println!("REQ: {req:?}");
    "Hello world!"
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
    log::info!("starting HTTP server at http://192.168.77.129:8000");
    
    let server = HttpServer::new(|| {
        App::new()
            .wrap(middleware::Logger::default())
            .service(web::resource("/index.html").to(|| async {"Hello html!"}))
            .service(web::resource("/").to(index))
    });
    server.bind("0.0.0.0:8000")?
        .run()
        .await
}

#[cfg(test)]
mod tests {
    use actix_web::{body::to_bytes, dev::Service, http, test, Error};
    use super::*;

    #[actix_web::test]
    async fn test_index() -> Result<(), Error> {
        let app = App::new().route("/", web::get().to(index));
        let app = test::init_service(app).await;

        let req = test::TestRequest::get().uri("/").to_request();
        let resp = app.call(req).await?;
        assert_eq!(resp.status(), http::StatusCode::OK);

        let response_body = resp.into_body();
        assert_eq!(to_bytes(response_body).await?, r##"Hello world!"##);

        Ok(())
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

执行测试:

(base) zhangdapeng@zhangdapeng:~/code/rust/hello$ cargo test
warning: `/home/zhangdapeng/.cargo/config` is deprecated in favor of `config.toml`
note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml`
warning: `/home/zhangdapeng/.cargo/config` is deprecated in favor of `config.toml`
note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml`
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.14s
     Running unittests src/main.rs (target/debug/deps/hello-4420b7c0e788b52b)

running 1 test
test tests::test_index ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/609488
推荐阅读
相关标签
  

闽ICP备14008679号