You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust Poem OpenAPI多段路径匹配:单处理器适配可变路径段

解决poem::openapi路径匹配多段namespace的问题

要让处理器同时匹配/mynamespace/myid和/mynamespace/mydomain/myid这类路径,将任意前置路径段存入namespace、最后一段存入id,可以借助poem的通配符路径捕获结合手动拆分路径的方式实现,同时保留SharedHandle的使用。

步骤1:修改路由路径定义

将原有的#[oai(path = "/:namespace/:id", method = "get")]替换为通配符路径,捕获完整的路径内容:

#[oai(path = "/*full_path", method = "get")]

这里的*full_path会捕获请求URL中域名后的所有路径段(不包含开头的/)。

步骤2:在处理器中拆分路径

在处理函数内,将捕获到的full_path按/分割,提取最后一段作为id,剩余部分拼接为namespace,同时保留对SharedHandle的访问:

use poem::{error::BadRequest, web::Path, Json};
use poem_openapi::OpenApi;

#[derive(Clone)]
pub struct MyApi {
    pub handle: SharedHandle, // 保留你的SharedHandle定义
}

#[OpenApi]
impl MyApi {
    #[oai(path = "/*full_path", method = "get")]
    async fn get_resource(
        &self,
        Path(full_path): Path<String>,
    ) -> Result<Json<ResourceResponse>, BadRequest> {
        // 拆分路径段,过滤空字符串(处理连续/的情况)
        let path_segments: Vec<&str> = full_path.split('/').filter(|s| !s.is_empty()).collect();
        
        // 验证路径至少包含两段(namespace + id)
        if path_segments.len() < 2 {
            return Err(BadRequest("Invalid path: requires at least two segments".into()));
        }

        // 提取id和namespace
        let id = path_segments.last().unwrap().to_string();
        let namespace = path_segments[0..path_segments.len()-1].join("/");

        // 这里可以正常使用self.handle处理业务逻辑
        // 比如 let data = self.handle.fetch_data(&namespace, &id).await?;

        Ok(Json(ResourceResponse { namespace, id }))
    }
}

// 示例响应结构体
#[derive(serde::Serialize)]
struct ResourceResponse {
    namespace: String,
    id: String,
}

关键说明

  • 通配符捕获:poem的*通配符会捕获当前位置到URL结尾的所有路径内容,适合处理不确定数量的前置路径段场景。
  • 路径拆分逻辑:通过split('/')拆分后过滤空值,避免处理//这类无效路径;再通过切片操作分离namespace和id。
  • SharedHandle保留:由于处理器是MyApi结构体的方法,通过&self可以直接访问结构体中的SharedHandle,完全兼容原有使用方式。
  • 路由优先级:如果你的API还有其他更具体的路由(比如/static/*),请将当前处理器放在这些路由之后注册,避免拦截其他请求。

内容的提问来源于stack exchange,提问作者navicore

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:05:16