小工具知识网

当前位置: 首页 > 行业知识 > Rust web开发 ActixWeb 入门

行业知识

Rust web开发 ActixWeb 入门

2026-11-14 09:26:34 来源:互联网转载

Rust Actix Web 入门

目前,Actix Web 仍然是 Rust Web 后端生态系统中极其强大的竞争对手。尽管之前的事件可能对其产生影响,但它仍然很强大,并且是 Rust 中最受推荐的 Web 框架之一。最初基于同名的 actor 框架 ( actix ),后来它已经消失,并且 actix 现在仅用于 websocket 端点。

本文将主要讨论 v4.4。

Actix Web 入门

首先,使用 cargo init example-api 生成项目,将 cd 到该文件夹中,然后使用以下命令将 actix-web crate 添加到项目中:

cargo add actix-web

现在已经准备好开始了!如果想复制样板文件以直接编写您的应用程序,如下所示:

use actix_web::{web, App, HttpServer, Responder};#[get("/")]async fn index() -> impl Responder {    "Hello world!"}#[actix_web::main]async fn main() -> std::io::Result {    HttpServer::new(|| {        App::new().service(            // prefixes all resources and routes attached to it...            web::scope("/")                // ...so this handles requests for `GET /app/index.html`                .route("/", web::get().to(index)),        )    })    .bind(("127.0.0.1", 8080))?    .run()    .await}

Actix Web 中的路由

使用 Actix Web 时,大多数返回 实现actix_web::Responder trait 的函数都可以用作路由。请参阅下面的基本 Hello World 示例:

#[get("/")]async fn index() -> impl Responder {    "Hello world!"}

然后可以将此处理函数输入到 actix_web::App 中,然后将其作为参数传递给 HttpServer :

#[actix_web::main]async fn main() -> std::io::Result {    HttpServer::new(|| {        App::new().service(            // prefixes all resources and routes attached to it...            web::scope("/")                // ...so this handles requests for the base route                .route("/index.html", web::get().to(index)),        )    })    .bind(("127.0.0.1", 8080))?    .run()    .await}

现在,每当您访问 /index.html 时,它都应该返回“Hello world!”。但是,如果您想创建多个 子路由 类型,然后最后将它们全部合并到应用程序中,您可能会发现这种方法有点缺乏。在这种情况下,您将需要 ServiceConfig 类型,您也可以这样写:

use actix_web::{web, App, HttpResponse};// this function could be located in different modulefn config(cfg: &mut web::ServiceConfig) {    cfg.service(web::resource("/test")        .route(web::get().to(|| HttpResponse::Ok()))        .route(web::head().to(|| HttpResponse::MethodNotAllowed()))    );}#[actix_web::main]async fn main() -> std::io::Result {    HttpServer::new(|| {        App::new().configure(config)    })    .bind(("127.0.0.1", 8080))?    .run()    .await}

Actix Web 中的提取器(Extractor)正是这样的:实现类型安全的请求,当传递到处理函数时,将尝试从处理函数的请求中提取相关数据。例如, actix_web::web::Json 提取器将尝试从请求正文中提取 JSON。然而,要成功反序列化 JSON,您需要使用 serde 包 - 最好与 derive 函数一起使用,为您的结构添加自动反序列化和序列化派生宏。您可以通过执行以下命令来安装 serde:

cargo add serde -F derive

现在可以将其用作派生宏,如下所示:

use actix_web::web;use serde::Deserialize;#[derive(Deserialize)]struct Info {    username: String,}// deserialize `Info` from request's body#[post("/submit")]async fn submit(info: web::Json) -> String {    format!("Welcome {}!", info.username)}

Actix Web 还支持 paths, queries and forms。您还需要在此处使用 serde - 尽管对于paths,您还需要使用 Actix Web 路由宏来声明路径参数的确切位置。我们可以在下面找到所有这 3 种方法的示例:

#[derive(Deserialize)]struct Info {    username: String,}// extract path info using serde#[get("/users/{username}")] //  String {    format!("Welcome {}!", info.username)}// data is passed in here through query parameters in the URL// for example, google.com/?hello=world#[get("/")]async fn index(info: web::Query) -> String {    format!("Welcome {}!", info.username)}// data is passed into the Form extractor through a HTML Form element#[post("/")]async fn index(form: web::Form) -> actix_web::Result {    Ok(format!("Welcome {}!", form.username))}

有兴趣编写自己的提取器吗?你可以做到的!编写自己的提取器只需要实现 FromRequest 特征。查看 HTTP 标头提取器的这段代码,它向您展示了它的具体工作原理:

use actix_web::dev::Payload;use actix_web::{FromRequest,    http::header::Header as ParseHeader,    HttpRequest, error::ParseError};#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)]pub struct Header(pub T);impl FromRequest for Headerwhere    T: ParseHeader,{    type Error = ParseError;    type Future = Ready;    #[inline]    fn from_request(req: &HttpRequest, _: &mut Payload) -> Self::Future {        match T::parse(req) {            Ok(header) => ok(Header(header)),            Err(e) => err(e),        }    }}

请注意, T: ParseHeader trait 约束 特定于此特征实现,因为为了使header有效,它需要能够成功解析为header,并在实现 actix_web::error::Error 。虽然我们也有 extract 作为提供的方法,但 from_request 是这里唯一需要实现的方法,它返回 Self::Future 。也就是说,我们需要返回一个 已准备好等待的结果(ready to be awaited) - 您可以在此处找到有关 Ready 结构的更多信息。其他提取器(例如 JSON 提取器)也允许您更改其配置 - 您可以在此文档页面中找到有关它的更多信息。

一般来说,responses只需要实现 actix_web::Responder trait就能够响应。尽管在实际响应类型方面已经有广泛的实现,因此您通常不需要实现自己的类型,但在某些特定的用例中这可能会很有帮助;例如,能够记录您的应用程序可能具有的所有类型的响应。

连接到数据库

通常,在设置数据库时,您可能需要设置数据库连接:

use sqlx::PgPoolOptions;#[actix_web::main]async fn main() -> std::io::Result {    let dbconnection = PgPoolOptions::new()        .max_connections(5)        .connect(r#""#).await;    //... rest of your code}

然后,您需要配置自己的 Postgres 实例,无论是本地安装在计算机上、通过 Docker 还是其他方式配置。但是,使用 Shuttle,我们可以消除这种情况,因为运行时会为您配置数据库:

use actix_web::{get, web::ServiceConfig};use shuttle_actix_web::ShuttleActixWeb;#[shuttle_runtime::main]async fn actixweb(    #[shuttle_shared_db::Postgres] pool: PgPool,) -> ShuttleActixWeb

上一篇:手机下载空调遥控器的简易指南

下一篇:nat服务器怎么设置?