1.1 Hello world

2022-09-26

开始

一个简单的 Hello world 程序,就会占掉 1 Gb 左右的存储空间。所以为了避免重复编译浪费磁盘空间,有必要利用到 rust 的工作空间。

新建一个文件夹,命名为 actix-study。进入文件夹之后,创建文件 Cargo.toml。打开 Cargo.toml,输入下面的内容。其中 members 内的成员就是我们之后要创建的项目了。

[workspace]

members = [
    "ch01/helloworld",
]

然后再创建一个文件夹,命名为 ch01。进入 ch01,输入下面的指令创建项目。

cargo new helloworld

进入 helloworld 文件夹,我这边使用 vscode 打开文件夹。目前没有任何内容。

打开项目的 Cargo.toml,在 [dependencies] 下添加 actix-web的引用,使用最新的版本 4.2.1。内容如下:

actix-web="4.2.1"

打开 main.rs 文件。主函数需要改成如下形式:

use actix_web::{HttpServer, App};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

首先可以注意到这里用到了 #[actix_web::main] 宏。在官方文档中提到,这个宏用于标记 actix-web 异步程序的入口,并且在 4.0 版本之前,使用的宏为 #[actix_rt::main]。总之就是用宏标记的函数,可以看作一般程序中的主函数。

HttpServer::new() 用于创建一个 Http 服务器。直接 new 就行,非常方便。先不关注 new 函数中的匿名函数内容。可以看到在 new 函数之后,链式调用了 bindrun 函数。其中 bind 函数用于绑定 IP 地址和端口,传入的参数为一个元组,前者为字符串,为 IP 地址;后者为一个无符号整型数据,即端口号。

run 为运行该服务器,在官方文档中,描述为开始监听传入连接。在没有绑定地址或者没有没有设置 tokio 运行时会报错。

现在回到 HttpServer::new() 的内容。里面只有非常简单的一段代码 App::new()。其中 App 可以在后面帮助构建程序并且配置各种参数。

现在如果运行程序,并访问 127.0.0.1:8080localhost:8080,什么都得不到。

返回 Hello world

为了显示 Hello world,需要新建一个函数。在 main.rs 中添加下面的函数:

async fn helloworld() -> impl Responder {
    HttpResponse::Ok().body("Hello world")
}

如果使用的不是 vscode 或者 vscode 没有安装 rust 的插件,需要修改顶部引用为:

use actix_web::{HttpServer, App, Responder, HttpResponse};

现在有了一个可以返回 Hello world 的函数。那么怎么使用这个函数呢?有两种方式。一种是通过宏来给这个函数配置路由,另一种是通过 App 来配置路由。当配置路由之后,访问相应的路径就可以看到返回的文本了。

宏配置

添加宏之前,先添加需要使用的宏的引用:

use actix_web::get;

然后在函数签名上添加宏 #[get("/")],添加之后的函数如下:

#[get("/")]
async fn helloworld() -> impl Responder {
    HttpResponse::Ok().body("Hello world")
}

宏中传入的字符串,代表的就是想要指定的路由。

宏添加好了。回到 main 函数中,在 App::new() 之后,调用 service 方法,将配置好路由的函数 helloworld 作为参数传入。代码如下:

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(helloworld)
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

现在重新运行,并访问对应地址,没有错误的话应该会显示出 Hello world 了。

直接配置路由

现在删除掉上面配置的 get 宏,并删除 service 的调用。在顶部引用添加 web 的引用:

use actix_web::web;

然后在 App::new() 之后调用方法 route。第一个参数为想要指定的路由地址,第二个为指定路由的 Http 请求。此处指定为 get 请求,并配置句柄为 helloworld。代码如下:

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to(helloworld))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

运行之后,可以得到和第一个方法一样的结果。

总结

actix-web 的服务器通过新建 HttpServer 并绑定地址启动,其中 App 可以配置路由。配置路由的方式有两种,一种是使用宏,然后在 App 中配置服务;另一种是直接配置路由。

而还有其他配置的方式,之后遇到再说了。

actix-web学习笔记Rustactix-web学习笔记

学少何

不求上进的社畜……

1.2 异常处理

Actix-web 学习笔记索引