小工具知识网

当前位置: 首页 > 行业知识 > Rust Web 框架入门和对比

行业知识

Rust Web 框架入门和对比

2026-11-06 11:30:52 来源:互联网转载

最适合使用的 Rust Web 框架

在 Web 开发的变化的浪潮中,Rust 已成为构建安全和高性能应用程序的首选语言。随着 Rust 的流行,一系列旨在利用其优势的 Web 框架也在不断出现。本文比较了一些最好的 Rust 框架,重点介绍了它们各自的优点和缺点,以帮助您为项目做出明智的决策。它还需要留心需要关注的框架,因为它们可能会改变我们在 Rust 中构建 Web 应用程序的方式。

由于大多数 Web 框架乍一看在使用上非常相似,但实际差异更加细微和琐碎。我希望强调文本中最重要的差异,但为了让您有更好的想法,我还展示了每个框架的示例代码,这些框架的作用不仅仅是简单的 hello world。所有示例均取自各自的 GitHub 存储库。

另请注意,这个列表绝不是详尽的,我肯定错过了一些现有的框架。如果您想包含您最喜欢的框架,请在 Twitter 或 Mastodon 上与我联系。

流行的 Rust 框架

Axum

Axum 是一个在 Rust 生态系统中具有特殊地位的 Web 应用程序框架。它是 Tokio 项目的一部分,该项目是使用 Rust 编写异步网络应用程序的运行时。 Axum 不仅使用 Tokio 作为其异步运行时,而且还与 Tokio 生态系统中的其他库集成,利用 Hyper 作为其 HTTP 服务器,并使用 Tower 作为中间件。这样,开发人员就能够重用 Tokio 生态系统中的现有库和工具。

Axum 还致力于在不依赖宏的情况下提供一流的开发人员体验,而是利用 Rust 的类型系统来提供安全且符合人体工程学的 API。这是通过使用特征来定义框架的核心抽象来实现的,例如 Handler 特征,它用于定义应用程序的核心逻辑。这种方法允许开发人员轻松地从较小的组件组​​成应用程序,这些组件可以在多个应用程序中重复使用。

Axum 中的处理程序是一个接受请求并返回响应的函数。这与其他后端框架类似,但利用 Axum 的 FromRequest trait,开发人员可以指定应从请求中提取的数据类型。返回类型需要实现 IntoResponse trait,并且已经有许多类型实现了此trait,包括允许轻松更改的元组类型,例如响应的状态代码。

如果您曾经使用过 Rust 的类型系统、泛型,尤其是trait中的异步方法(或更具体地说:返回的 Future ),您就会知道当您不满足 trait 约束(bound) 时,Rust 的错误消息会变得多么复杂。尤其是当您尝试适配 抽象 trait 约束(bound)时,经常会发生这样的情况:您会看到一堵难以破译的文本墙。改变几行的顺序,就没有任何作用了! Axum 提供了一个带有辅助宏的库,可以将错误定位到实际发生的位置,从而更容易理解出了什么问题。

Axum 做了很多正确的事情,并且很容易启动执行大量操作的应用程序。但是,您需要注意一些事项。该版本仍低于 1.0,Axum 团队可以从根本上更改版本之间的 API,这可能会导致您的应用程序崩溃。我们知道,这就是 0.x 版本的处理方式,但有些更改似乎非常微妙,但需要您开发一种不同的思维模型来了解底层的工作原理。如果您包含一个 Timeout 层(内置在 Tower 中),它在一个版本中可以轻松工作,在另一个版本中需要一个捕获所有错误处理程序,在下一个版本中需要一个绑定错误处理程序。这不是什么大问题,但当您尝试完成工作或使用最新版本启动项目并且事情突然发生变化时,可能会令人沮丧。此外,虽然您能够利用整个 Tokio 生态系统,但有时您需要处理粘合类型和特征,而不是直接使用 Tokio 函数。一个例子是使用任何与流和(网络)套接字相关的内容。

好的例子会有所帮助,但您需要持续跟踪。

尽管如此,Axum 是我个人最喜欢的,也是我用于 Shuttle Launchpad 的框架。我喜欢它的表现力和背后的概念,通过理解正确的概念,我想解决的问题都是我无法凭直觉完成的。如果您想了解 Axum 概念,请查看我的 Tokio + 微服务研讨会上的幻灯片。

Axum Example

Axum 仓库中的一个简短示例显示了一个 WebSocket 处理程序,该处理程序会回显它收到的任何消息。

#[tokio::main]async fn main() {    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")        .await        .unwrap();    println!("listening on {}", listener.local_addr().unwrap());    axum::serve(listener, app()).await.unwrap();}fn app() -> Router {    // WebSocket routes can generally be tested in two ways:    //    // - Integration tests where you run the server and connect with a real WebSocket client.    // - Unit tests where you mock the socket as some generic send/receive type    //    // Which version you pick is up to you. Generally we recommend the integration test version    // unless your app has a lot of setup that makes it hard to run in a test.    Router::new()        .route("/integration-testable", get(integration_testable_handler))        .route("/unit-testable", get(unit_testable_handler))}// A WebSocket handler that echos any message it receives.//// This one we'll be integration testing so it can be written in the regular way.async fn integration_testable_handler(ws: WebSocketUpgrade) -> Response {    ws.on_upgrade(integration_testable_handle_socket)}async fn integration_testable_handle_socket(mut socket: WebSocket) {    while let Some(Ok(msg)) = socket.recv().await {        if let Message::Text(msg) = msg {            if socket                .send(Message::Text(format!("You said: {msg}")))                .await                .is_err()            {                break;            }        }    }}
Axum总结
  • Macro-free API.
  • 利用 Tokio、Tower 和 Hyper 建立强大的生态系统。
  • 很棒的开发者经验。
  • 仍处于 0.x 版本,因此可能会发生重大更改。

    Actix Web Actix

    Actix Web 是 Rust 的 Web 框架之一,已经存在了一段时间,因此非常受欢迎。与任何优秀的开源项目一样,它经历了多次迭代,但它已经达到了 0 以上的主要版本,并保持了稳定性保证:在主要版本内,您可以确保没有重大更改。

    当我们谈论 Actix Web 时,很容易假设它是基于 actix actor 运行时的。然而,这种情况已经有 4 年多没有发生了; Actix Web 中唯一需要 actor 的剩余部分是 WebSocket,但我们正在努力完全删除其使用,因为 actix 无法与现代异步 Rust 世界很好地配合。更广泛的 Actix 项目和 GitHub org 提供了许多用于构建并发应用程序的库,从较低级别的 TCP 服务器构建器,到 HTTP / Web 层,一直到静态文件提供程序和会话管理crate。

    乍一看,Actix Web 看起来与 Rust 中的其他 Web 框架非常熟悉。您使用宏来定义 HTTP 方法和路由(如 Rocket),并使用提取器从请求中获取数据(如 Axum)。与 Axum 的相似之处是惊人的,在概念和特征的命名方式上也是如此。最大的区别是 Actix Web 并没有将自己与 Tokio 生态系统联系得太紧密。虽然 Tokio 仍然是 Actix Web 下的运行时,但该框架具有自己的抽象和特征,以及自己的crate生态系统。这有优点也有缺点。一方面,您可以确定事物通常可以很好地协同工作,另一方面,您可能会错过 Tokio 生态系统中已经提供的许多事物。

    让我感到奇怪的一件事是 Actix Web 实现了自己的 Service trait,它与 Tower 的基本相同,但仍然不兼容。这意味着 Tower 生态系统中的大多数可用中间件不适用于 Actix。

    同样有趣的是,如果您需要在 Actix Web 中自行实现一些特殊任务,您可能会遇到运行框架中所有内容的 Actor 模型。这可能会增加一些您可能不想处理的复杂性。

    但 Actix Web 周围的社区提供了这一点。该框架支持 HTTP/2 和 Websocket 升级,它具有 Web 框架中最常见任务的包和指南,优秀的(我的意思是优秀的)文档,而且速度很快。 Actix Web 的流行是有原因的,如果您需要保持版本保证,它可能是您现在的最佳选择。

    Actix Web Example

    Actix Web 中的简单 WebSocket 回显服务器如下所示:

    use actix::{Actor, StreamHandler};use actix_web::{web, App, Error, HttpRequest, HttpResponse, HttpServer};use actix_web_actors::ws;/// Define HTTP actorstruct MyWs;impl Actor for MyWs {    type Context = ws::WebsocketContext;}/// Handler for ws::Message messageimpl StreamHandler for MyWs {    fn handle(&mut self, msg: Result, ctx: &mut Self::Context) {        match msg {            Ok(ws::Message::Ping(msg)) => ctx.pong(&msg),            Ok(ws::Message::Text(text)) => ctx.text(text),            Ok(ws::Message::Binary(bin)) => ctx.binary(bin),            _ => (),        }    }}async fn index(req: HttpRequest, stream: web::Payload) -> Result {    let resp = ws::start(MyWs {}, &req, stream);    println!("{:?}", resp);    resp}#[actix_web::main]async fn main() -> std::io::Result {    HttpServer::new(|| App::new().route("/ws/", web::get().to(index)))        .bind(("127.0.0.1", 8080))?        .run()        .await}
    Actix Web 总结
    • 强大、独立的生态系统。
    • Actor model based.
    • 通过主要版本保证实现稳定的 API。
    • 很棒的文档。

      Rocket

      Rocket 长期以来一直是 Rust Web 框架生态系统中的明星,它对开发人员体验的态度毫无歉意,对熟悉的现有概念的依赖,以及提供包含丰富内置功能的体验的雄心勃勃的目标。

      当您进入他们漂亮的网站时,您可以看到它的野心:基于宏的路由、内置表单处理、对数据库和状态管理的支持,以及它自己的模板版本! Rocket 确实尝试完成构建 Web 应用程序所需的一切。

      然而,Rocket的野心却付出了代价。虽然仍在积极开发中,但发布并不像以前那么频繁。这意味着该框架的用户会错过很多重要的东西。

      此外,由于采用了包含丰富内置功能的方法,您还需要了解 Rocket 是如何工作的。 Rocket 应用程序有生命周期,构建块以特定方式连接,如果出现问题,您需要了解问题所在。

      Rocket 是一个很棒的框架,如果你想开始 Rust Web 开发,它是一个不错的选择。就我个人而言,我对 Rocket 情有独钟,希望它的发展能够加快。对于我们许多人来说,Rocket 是第一个进入 Rust 的人,用它进行开发仍然很有趣。尽管如此,我通常依赖 Rocket 中不可用的功能,因此我不会在生产中使用它。

      Rocket Example

      Rocket 应用程序的一个简短示例,用于处理示例存储库中的表单:

      #[derive(Debug, FromForm)]struct Password

上一篇:DHCP自动获取IP地址实验(华为)

下一篇:gbk怎么打开?