Rust Web 开发 II

路由、中间件

技术
技术RustWeb 开发后端框架

2026-04-05

上一篇文章,我简要概述了 Axum 框架的基本组成。这篇文章,我将详细展开讲讲路由和中间件。

路由

路由(routing)是分发请求的中枢。所有发往服务器的请求都要先过路由这一关,它负责将请求按照其 URL 路径和请求方法进行匹配,匹配成功就让对应的中间件(如果有的话)和处理器去处理,否则就返回 404 Not Found

Axum 中,路由由 Router 实现。一个 Router 能使用 .route 方法注册多个路由,这个方法接收一条 &str 路径和一个 MethodRouter 实例。

  1. 路径可以是静态的(例如 //foo/users/123),也可以是捕获性的,还可以是通配符

    • 捕获性的路径需使用花括号包裹路径段,它可以将对应的路径参数捕获为一个同名变量,后续可以使用提取器在处理器中使用这个变量。

      比如 /{key} 会匹配像 /mykey/1234 这样的路径,并将字符串 mykey1234 存储在变量 key 当中;同理,/users/{id}/tweets 会匹配路径 /users/1104/tweets 并将 1104 存储在变量 id 当中。

    • 通配符路径只需要在捕获性路径的捕获变量前加 * 即可,它会匹配剩余所有路径段,但不会匹配空路径段。相比捕获性路径,它只能出现在路径末尾;它和前者一样有捕获功能。

      比如 /{*key} 会匹配 /a/a/ 等路径,但不匹配 //assets/{*path} 不匹配 /assets/,但匹配 /assets/styles.css/assets/image/img.jpg 等。

  2. MethodRouter 实例通常是借助方法路由函数构造的。

    方法路由是一系列在 axum::routing::method_routing 中定义的函数,它们都接收一个处理器并返回一个 MethodRouter 实例。

    use axum::{
        routing::any,
        Router,
    };
    
    /// 这是一个处理器
    async fn handler() {}
    
    // 创建路由,匹配 `/` 路径
    //
    // 这里的 `any` 函数就是方法路由
    // 它接收一个处理器并构造出 `MethodRouter`
    let app = Router::new().route("/", any(handler));
    

    以下是常用的方法路由:

    函数名 含义
    any 匹配任意请求方法
    get 只匹配 GET 请求
    post 只匹配 POST 请求

    方法路由还允许进行链式调用。

    async fn handler() {}
    
    async fn other_handler() {}
    
    // `POST /` 请求交给 `other_handler`,其它则都由 `handler` 处理
    let app = Router::new().route("/", any(handler).post(other_handler));