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

相关推荐
LuckyLay38 分钟前
使用 Docker 搭建 Rust Web 应用开发环境——AI教你学Docker
前端·docker·rust
pobu1681 小时前
aksk前端签名实现
java·前端·javascript
烛阴1 小时前
带参数的Python装饰器原来这么简单,5分钟彻底掌握!
前端·python
0wioiw01 小时前
Flutter基础(前端教程⑤-组件重叠)
开发语言·前端·javascript
冰天糖葫芦1 小时前
VUE实现数字翻牌效果
前端·javascript·vue.js
SoniaChen331 小时前
Rust基础-part3-函数
开发语言·后端·rust
南岸月明1 小时前
我与技术无缘,只想副业搞钱
前端
全干engineer2 小时前
Flask 入门教程:用 Python 快速搭建你的第一个 Web 应用
后端·python·flask·web
William一直在路上2 小时前
SpringBoot 拦截器和过滤器的区别
hive·spring boot·后端
gzzeason2 小时前
在HTML中CSS三种使用方式
前端·css·html