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

如何使用Rocket(Rust)实现指定结构的JSON响应?

Rocket Web服务统一响应实现方案

1 错误处理方案选择

  • 业务层面的自定义错误直接使用派生Responder的枚举实现即可,不需要使用catcher。这种方案可以在路由逻辑中直接返回错误变体,灵活控制自定义错误的状态码和返回信息。
  • catcher仅用于处理框架层面的全局错误(如路由404、权限校验失败等框架主动抛出的异常),如果需要这部分错误也符合你定义的响应格式,可以配套实现对应catcher。

正确的APIError定义示例:

use rocket::http::Status;
use rocket::Responder;
use serde::Serialize;

// 错误内层结构,对应响应中的error字段内容
#[derive(Serialize)]
struct ErrorInner {
    status_code: u16,
    message: String,
}

// 错误外层包装,保证序列化结构符合要求
#[derive(Serialize)]
struct APIErrorWrapper {
    error: ErrorInner
}

// 自定义错误枚举
#[derive(Responder)]
#[response(content_type = "json")]
pub enum APIError {
    #[response(status = 404)]
    NotFound(serde_json::Value),
    #[response(status = 400)]
    BadRequest(serde_json::Value),
    #[response(status = 500)]
    InternalError(serde_json::Value),
}

// 实现错误构造方法,简化调用
impl APIError {
    pub fn not_found(msg: String) -> Self {
        let wrapper = APIErrorWrapper {
            error: ErrorInner {
                status_code: Status::NotFound.code,
                message: msg
            }
        };
        Self::NotFound(serde_json::to_value(wrapper).unwrap())
    }
}

2 成功响应结构定义

你当前的结构缺失了外层的data字段,需要额外套一层结构即可。Vec<String>原生支持serde序列化,不需要额外实现trait,只要你已经启用了rocket的json功能特性。

示例代码:

#[derive(Serialize)]
struct Data {
    topics: Vec<String>,
}

// 成功响应外层结构
#[derive(Serialize)]
struct SuccessWrapper {
    data: Data
}

#[derive(Responder)]
#[response(content_type = "json", status = 200)]
pub struct SuccessResp(serde_json::Value);

// 构造方法示例
impl SuccessResp {
    pub fn new(topics: Vec<String>) -> Self {
        let wrapper = SuccessWrapper {
            data: Data { topics }
        };
        Self(serde_json::to_value(wrapper).unwrap())
    }
}

3 统一响应枚举实现

建议合并为统一的Response枚举,这样路由的返回值类型统一,代码更易维护。
实现示例:

#[derive(Responder)]
pub enum APIResponse {
    Success(SuccessResp),
    Error(APIError),
}

使用时在路由中直接返回对应变体即可:

#[get("/topics")]
pub async fn get_topics() -> APIResponse {
    // 模拟业务逻辑
    let is_success = true;
    if is_success {
        let topics = vec!["topic1".to_string(), "topic2".to_string()];
        APIResponse::Success(SuccessResp::new(topics))
    } else {
        APIResponse::Error(APIError::not_found("topics not exist".to_string()))
    }
}

最后需要在Cargo.toml中添加必要依赖:

[dependencies]
rocket = { version = "0.5.0-rc.3", features = ["json"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 04:51:03