Actix-Web 中定义路由的5种方法

一、开始

本文主要讲解,如何初始化一个 actix-web 项目,以及各种定义路由方式。

二、初始化一个项目

首先需要有 rust 的运行环境,使用 Rust Cargo 初始一个项目:

sh 复制代码
cargo new <your_project_name>
  • 添加依赖
toml 复制代码
[dependencies]  
actix-web = "4"
  • 一个最简单的应用
rs 复制代码
use actix_web::{get, App, HttpResponse, HttpServer, Responder};

#[get("/")]
async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

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

分析:从 actix_web 包中,导入了 HTTP 相关的内容,HttpServer 用于初始化 HTTP 服务,App 用于初始化 应用服务,HttpServer 实例化的过程汇总需要一个闭包函数,在闭包函数中实例化 App, 并且在 App 中定义好路由。接下来就可以启动此服务了。

  • 运行服务
sh 复制代码
cargo run

三、定义路由的各种方法

3.1)route 函数单独定义

rs 复制代码
use actix_web::{App, web, HttpResponse, HttpServer, Responder};

async fn hello() -> impl Responder {
    HttpResponse::Ok().body("Hello world!")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .route("/", web::get().to(hello))
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

此处使用 route 函数进行定义,需要 web 配合指定,方法是 get 已及它的处理函数是 hello

3.2)service 函数单独定义

  • 以 post 方法为例
rs 复制代码
use actix_web::{post, App, HttpResponse, HttpServer, Responder};

#[post("/")]
async fn echo(req_body: String) -> impl Responder {
    HttpResponse::Ok().body(req_body)
}

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

service 与 route 不同的是, service 是通过 rust 注解的形式获取定义请求的方式和路由参数。

3.3)resource 函数成组定义

rs 复制代码
pub fn resource<T: IntoPatterns>(path: T) -> Resource {
    Resource::new(path)
}
  • 定义资源群 resource,以下示例是:
rs 复制代码
use actix_web::{web, App, HttpResponse, HttpServer, Responder};

async fn users_list() -> impl Responder {
    HttpResponse::Ok().body("List of users")
}

async fn user_info(path: web::Path<(String,)>) -> impl Responder {
    let username = &path.0;
    HttpResponse::Ok().body(format!("User info for: {}", username))
}

async fn create_user() -> impl Responder {
    HttpResponse::Created().body("User created successfully")
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    HttpServer::new(|| {
        App::new()
            .service(
                web::resource("/users")
                    .route(web::get().to(users_list)) // GET /users
                    .route(web::post().to(create_user)), // POST /users
            )
            .service(
                web::resource("/users/{username}")
                    .route(web::get().to(user_info)), // GET /users/{username}
            )
    })
    .bind("127.0.0.1:8080")?
    .run()
    .await
}

resource 定义一个路由资源,此时就可以使用 route 方法处理不同方法的请求。在此实例中,使用 service 方法 与 web::resource 进行配合可以成组使用。service 单独使用的案例之前已经说过了。

3.4)configure 函数自定定义配置路由

rs 复制代码
use actix_web::{web, App, HttpResponse, HttpServer};

fn config(cfg: &mut web::ServiceConfig) {
    cfg.service(
        web::resource("/app")
            .route(web::get().to(|| async { HttpResponse::Ok().body("app") }))
            .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
}

configure 方法能够定义 config 函数,在 config 函数中,获取 cfg 对象,cfg 中存在 service, 相当于一个子服务。在模块拆分的时候非常有用。

3.5) scope 函数定义作用域

rs 复制代码
use actix_web::{web, App, HttpServer, Responder};

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("/app")
                // ...so this handles requests for `GET /app/index.html`
                .route("/index", web::get().to(index)),
        )
    })
    .bind(("127.0.0.1", 8080))?
    .run()
    .await
}

web::scope 的用法与 web::resource 用法类似,后者针对于当前资源使用不同的方式处理,前者可以定义子路由,并指定不同的方法。scope 更加的灵活

四、小结

本文主要关注 actix-web 中定义路由的多种方式。从一个简单的示例开始,到route 函数的单独订立,然后是 service 函数定义,resource 函数定义统一方法的多重处理方式,configure 函数可以可以拆分函数配置,scope 使用作用域配置与 resource 类似,但是更加灵活。

相关推荐
Gopher_HBo1 分钟前
Go进阶string原理和高效实用
后端
Memory_荒年2 分钟前
马年驯服不稳定服务:Resilience4j 容错救星驾到!
java·后端
楼田莉子3 分钟前
高并发内存池项目:内存池性能分析及其优化
开发语言·c++·后端·学习
Leo655354 分钟前
动态 SQL(行+列) + 动态表头(前端+EasyPoi) = 完整透视报表系统
前端·sql·状态模式
Gary jie4 分钟前
OpenClaw启动日志详细分析
前端·chrome
rannn_1116 分钟前
【Redis|实战篇4】黑马点评|分布式锁
java·数据库·redis·分布式·后端
择势9 分钟前
macOS App 签名与公证流程详解及一键自动化
前端
爱摸鱼的打工仔10 分钟前
【python知识点-Flask中的g对象】
后端
umeelove3516 分钟前
Spring 循环依赖
java·后端·spring
英俊潇洒美少年21 分钟前
Vue3 中 watch的 flush 选项(默认无/`post`/`sync`)的区别
前端·javascript·vue.js