Actix-web 简介
Actix-web 是一个高性能的、模块化的异步 Web 框架,专为构建网络服务而设计。它建立在 Rust 的异步运行时 Actix 上,提供了丰富的功能和优秀的性能。Actix-web 支持多种特性,包括路由、中间件、模板引擎等。
安装 Actix-web
首先,你需要在你的 Cargo.toml 文件中添加 Actix-web 作为依赖项:
[dependencies]
actix-web = "4"
futures = "0.3"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"这些依赖项包括了 Actix-web 本身,以及一些常用的库,如 futures 和 serde。futures 库提供了处理异步代码的功能,而 serde 则是一个序列化和反序列化的库,可以用于处理 JSON 数据。
创建一个基本的 Web 应用
接下来,我们将创建一个简单的 Web 应用,该应用将提供一个 API 端点来响应 GET 请求,并返回一段 JSON 字符串。
创建项目结构
首先,确保你已经安装了 Rust 和 Cargo。然后,使用以下命令创建一个新的 Cargo 项目:
cargo new actix-web-example cd actix-web-example
在项目的根目录下,你会看到 src/main.rs 文件,这是应用程序的入口点。接下来,我们将修改这个文件,引入 Actix-web 并设置一个简单的 API。
编写基本的 Web 服务器代码
打开 src/main.rs 文件,并替换其内容为以下代码:
// www.javascriptcn.com code example
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Greeting {
message: String,
}
async fn index() -> impl Responder {
let greeting = Greeting {
message: "Hello from Actix-web!".to_string(),
};
HttpResponse::Ok().json(greeting)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
})
.bind("127.0.0.1:8080")?
.run()
.await
}这段代码定义了一个简单的 Web 服务器,它监听 127.0.0.1:8080 地址,并通过 GET 请求返回一个 JSON 响应。我们使用了 serde 库来处理 JSON 的序列化和反序列化。
运行你的第一个 Actix-web 应用
保存并退出编辑器,然后在终端中运行以下命令启动服务器:
cargo run
你应该会看到类似以下的日志输出:
Finished dev [unoptimized + debuginfo] target(s) in 0.02s Running `target/debug/actix-web-example` [2023-09-18T09:59:28Z INFO actix_server] Starting 4 workers [2023-09-18T09:59:28Z INFO actix_server] Actix-web = started server [0.0.0.0:8080]
这意味着你的 Web 服务器正在运行。你可以通过浏览器访问 http://127.0.0.1:8080 或者使用 curl 工具来验证你的 API 是否正常工作:
curl http://127.0.0.1:8080
你应该会看到如下输出:
{"message":"Hello from Actix-web!"}恭喜!你已经成功地使用 Actix-web 创建了一个简单的 Web 应用程序。
路由和处理函数
Actix-web 提供了强大的路由功能,允许你根据请求的方法(GET、POST 等)和路径来分发请求到不同的处理函数。接下来,我们将扩展我们的示例,增加更多的路由和处理逻辑。
添加更多路由
我们将添加一个新的路由来处理 POST 请求,并接收 JSON 数据作为输入。
修改主函数
在 src/main.rs 文件中,我们将在现有的路由基础上添加一个新的路由:
// www.javascriptcn.com code example
async fn handle_post(req_body: String) -> impl Responder {
let data: Greeting = serde_json::from_str(&req_body).unwrap();
HttpResponse::Ok().json(data)
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.route("/", web::get().to(index))
.route("/post", web::post().to(handle_post))
})
.bind("127.0.0.1:8080")?
.run()
.await
}这里我们添加了一个新的处理函数 handle_post,它接受一个 POST 请求,并将请求体解析成一个 Greeting 结构体。然后,它将接收到的数据原样返回。
测试新路由
现在,让我们测试一下新的 POST 路由。你可以使用 curl 工具发送一个 POST 请求:
curl -X POST -H "Content-Type: application/json" -d '{"message": "Hello Actix-web!"}' http://127.0.0.1:8080/post你应该会看到如下输出:
{"message":"Hello Actix-web!"}这表明你的新路由已经正确地处理了 POST 请求。
中间件
Actix-web 还支持中间件的概念,中间件可以在请求到达目标处理函数之前或之后执行一些操作。中间件可以用来实现日志记录、身份验证、压缩等功能。
创建一个简单的中间件
我们将创建一个中间件来记录每个请求的时间戳。
定义中间件
首先,在 src/main.rs 文件中,我们需要定义一个中间件:
// www.javascriptcn.com code example
use std::time::Instant;
async fn log_middleware(
req: actix_web::dev::ServiceRequest,
service: actix_web::dev::Service<actix_web::dev::ServiceRequest>,
) -> Result<actix_web::dev::ServiceResponse, actix_web::Error> {
let start = Instant::now();
let res = service.call(req).await?;
let latency = start.elapsed();
println!("Request took {:?}", latency);
Ok(res)
}这个中间件在请求开始时记录当前时间,并在请求结束时计算出请求所花费的时间,然后打印出来。
注册中间件
接着,我们需要在应用程序中注册这个中间件。修改 main 函数如下:
// www.javascriptcn.com code example
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(log_middleware) // 注册中间件
.route("/", web::get().to(index))
.route("/post", web::post().to(handle_post))
})
.bind("127.0.0.1:8080")?
.run()
.await
}现在,每次有请求到达时,都会记录请求所花费的时间。
测试中间件
再次启动你的应用并发送请求,你应该会在控制台看到类似于以下的输出:
Request took 67.72µs
这表明中间件已经被正确地应用到了你的应用中。
总结
通过以上步骤,我们已经介绍了如何使用 Actix-web 来创建一个简单的 Web 应用,并添加了路由和中间件。Actix-web 提供了丰富的功能和高性能,是构建现代 Web 应用的理想选择。希望你能继续探索 Actix-web 的其他功能,并开发出更加复杂和强大的应用。