开始
一个简单的 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 函数之后,链式调用了 bind
和 run
函数。其中 bind 函数用于绑定 IP 地址和端口,传入的参数为一个元组,前者为字符串,为 IP 地址;后者为一个无符号整型数据,即端口号。
run
为运行该服务器,在官方文档中,描述为开始监听传入连接。在没有绑定地址或者没有没有设置 tokio 运行时会报错。
现在回到 HttpServer::new()
的内容。里面只有非常简单的一段代码 App::new()
。其中 App
可以在后面帮助构建程序并且配置各种参数。
现在如果运行程序,并访问 127.0.0.1:8080
或 localhost: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 中配置服务;另一种是直接配置路由。
而还有其他配置的方式,之后遇到再说了。