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 类似,但是更加灵活。

相关推荐
Vicky&James8 分钟前
WPF到Web的无缝过渡:英雄联盟客户端项目OpenSilver迁移实战
前端·wpf
吃海鲜的骆驼10 分钟前
服务异步通讯与RabbitMQ
java·分布式·后端·rabbitmq
m0_7482336412 分钟前
RabbitMQ 进阶
android·前端·后端
不想有bug的小菜鸟20 分钟前
vue3使用iframe全屏展示pdf效果
前端·pdf
m0_7482386321 分钟前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
u01005596022 分钟前
前端代理,解决跨域问题讲解
前端
桦说编程23 分钟前
【硬核总结】如何轻松实现只计算一次、惰性求值?良性竞争条件的广泛使用可能超过你的想象!String实际上是可变的?
后端·函数式编程
quitv27 分钟前
react脚手架配置别名
前端·javascript·react.js
m0_5287238136 分钟前
前端如何进行性能优化
前端·性能优化
化作繁星37 分钟前
在 Vue 3 中,如何缓存和复用动态组件
前端·vue.js·缓存