Rust中使用rocket_okapi返回Result类型的OpenApiResponder错误解决
解决方案
1. 解决OpenApiResponder未实现的问题
Result<Json<Vec<DetailedReadingList>>, rocket::http::Status>默认未实现OpenApiResponder<'_> trait,你可以通过两种方式处理:
方法一:用OpenApiResponse包装错误类型
直接使用rocket_okapi提供的OpenApiResponse包装Status,让返回类型满足trait要求:
use rocket_okapi::response::OpenApiResponse; #[openapi] #[get("/lists")] async fn get_all_lists() -> Result<Json<Vec<DetailedReadingList>>, OpenApiResponse<rocket::http::Status>> { // 业务逻辑示例 Ok(Json(vec![])) }
方法二:自定义可序列化的错误枚举
如果需要更清晰的错误返回格式,定义自己的错误类型,派生Serialize和JsonSchema,同时实现Into<Status>和OpenApiResponder:
use rocket::http::Status; use rocket_okapi::gen::OpenApiGenerator; use rocket_okapi::response::OpenApiResponder; use schemars::JsonSchema; use serde::Serialize; #[derive(Debug, Serialize, JsonSchema)] enum ApiError { NotFound, InternalServerError, // 根据业务需求添加更多错误类型 } impl Into<Status> for ApiError { fn into(self) -> Status { match self { ApiError::NotFound => Status::NotFound, ApiError::InternalServerError => Status::InternalServerError, } } } impl<'r> OpenApiResponder<'r> for ApiError { fn responses(gen: &mut OpenApiGenerator) -> rocket_okapi::Result<mut openapi::Responses> { let mut responses = openapi::Responses::default(); // 为每个错误类型添加OpenAPI响应定义 responses.insert( Status::NotFound.to_string(), openapi::Response { description: "请求的资源不存在".to_string(), content: gen.json_schema::<ApiError>()?.into(), ..Default::default() }, ); responses.insert( Status::InternalServerError.to_string(), openapi::Response { description: "服务器内部错误".to_string(), content: gen.json_schema::<ApiError>()?.into(), ..Default::default() }, ); Ok(responses) } } // 路由使用自定义错误类型 #[openapi] #[get("/lists")] async fn get_all_lists() -> Result<Json<Vec<DetailedReadingList>>, ApiError> { // 业务逻辑,出错时返回Err(ApiError::NotFound)等 Ok(Json(vec![])) }
2. 避开Json<Result<...>>的序列化问题
rocket::http::Status本身没有实现Serialize trait,所以不能直接放到Json容器中序列化。上面两种方案都能绕过这个问题,同时满足OpenAPI规范生成的要求。
3. 确保依赖版本兼容
检查Cargo.toml中rocket和rocket_okapi的版本匹配,示例配置:
[dependencies] rocket = { version = "0.5.0-rc.3", features = ["json"] } rocket_okapi = { version = "0.12.0-rc.3", features = ["swagger", "json"] } schemars = "0.8.12" serde = { version = "1.0", features = ["derive"] } diesel = { version = "2.1.0", features = ["postgres", "r2d2", "serde_json"] } # 若使用Queryable
内容的提问来源于stack exchange,提问作者Omar Imtiaz
相关产品推荐
相关产品推荐

