自学内容网 自学内容网

# Rust Actix Web 入门指南

Rust Actix Web 入门指南

作者:Joshua Mo
日期:2023年12月15日

概述

  • Actix Web 入门
  • Actix Web 路由
  • 添加数据库
  • Actix Web 应用状态
  • 中间件
  • 静态文件服务
  • 部署
  • 总结

时至今日,Actix Web 仍然是 Rust Web 后端生态系统中极其强大的竞争者。尽管经历了一些事件,它依然保持强劲,成为 Rust 中最受推荐的 Web 框架之一。最初基于同名的 actor 框架(actix),现在已经脱离了原来的设计,现在 actix 主要用于 WebSocket 端点。

本文主要讨论 v4.4 版本。

Actix Web 入门

首先,使用 cargo init example-api 生成项目,然后进入项目目录,使用以下命令添加 actix-web 依赖:

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(
            web::scope("/")
                .route("/", web::get().to(index)),
        )
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

Actix Web 路由

在 Actix Web 中,任何返回 actix_web::Responder 特征的函数都可以作为路由。下面是一个基本的 Hello World 示例:

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

对于更复杂的路由配置,可以使用 ServiceConfig

use actix_web::{web, App, HttpResponse};

fn 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
}

提取器(Extractors)

Actix Web 提供了类型安全的请求提取器。例如,使用 JSON 提取器:

cargo add serde -F derive
use actix_web::web;
use serde::Deserialize;

#[derive(Deserialize)]
struct Info {
    username: String,
}

#[post("/submit")]
async fn submit(info: web::Json<Info>) -> String {
    format!("Welcome {}!", info.username)
}

支持路径、查询和表单提取:

#[derive(Deserialize)]
struct Info {
    username: String,
}

#[get("/users/{username}")]
async fn index(info: web::Path<Info>) -> String {
    format!("Welcome {}!", info.username)
}

#[get("/")]
async fn index(info: web::Query<Info>) -> String {
    format!("Welcome {}!", info.username)
}

#[post("/")]
async fn index(form: web::Form<Info>) -> actix_web::Result<String> {
    Ok(format!("Welcome {}!", form.username))
}

添加数据库

数据库连接示例:

use sqlx::PgPoolOptions;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let dbconnection = PgPoolOptions::new()
        .max_connections(5)
        .connect(r#"<数据库连接字符串>"#).await;

    // 其余代码
}

应用状态

在 Actix Web 中共享可变状态:

use sqlx::PgPool;

#[derive(Clone)]
struct AppState {
    db: PgPool
}

#[get("/")]
async fn index(data: web::Data<AppState>) -> String {
    let res = sqlx::query("SELECT 'Hello World!'").fetch_all(&data.db).await.unwrap();
    format!("{res}")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let db = connect_to_db();
    let state = web::Data::new(AppState { db });

    HttpServer::new(move || {
        App::new()
            .app_data(state.clone())
            .route("/", web::get().to(index))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

中间件

添加日志中间件:

use actix_web::{middleware::Logger, App};

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));

    let app = App::new()
        .wrap(Logger::default());

    // 其余代码
}

静态文件服务

cargo add actix-files
use actix_files as fs;
use actix_web::{App, HttpServer};

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

部署

使用 Shuttle 可以简化部署过程:

shuttle deploy

总结

Actix Web 是一个强大的 Rust Web 框架,非常适合构建高性能的 Web 应用。它提供了灵活的路由、强大的中间件支持,以及丰富的生态系统。


原文地址:https://blog.csdn.net/hzether/article/details/145240843

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!