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"

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
}

运行和访问

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

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

代码解读

引入依赖:

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

首页路由:

  • 获取请求信息:index(req: HttpRequest)
  • 返回一个纯文本字符串:&'static str
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"));
  • 记录一个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
}

测试代码

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(())
    }
}

完整代码:

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(())
    }
}

执行测试:

(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. Flask Web框架入门教程

    2024-05-16 11:36:11       14 阅读
  2. Web框架开发-Ajax(formData)

    2024-05-16 11:36:11       20 阅读
  3. Web框架开发-Django-缓存

    2024-05-16 11:36:11       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-16 11:36:11       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-16 11:36:11       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-16 11:36:11       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-16 11:36:11       18 阅读

热门阅读

  1. Ubuntu安装ZLMediaKit

    2024-05-16 11:36:11       14 阅读
  2. C++之lambda【匿名函数】

    2024-05-16 11:36:11       11 阅读
  3. MHA 高可用部署

    2024-05-16 11:36:11       9 阅读
  4. react + antd:新建项目问题汇总

    2024-05-16 11:36:11       10 阅读
  5. 引导前端学习

    2024-05-16 11:36:11       11 阅读
  6. C++并发:构建线程安全的队列

    2024-05-16 11:36:11       10 阅读
  7. 由读写arrow引发的对时间时区的思考

    2024-05-16 11:36:11       6 阅读