【问题标题】:Rocket - Status with json bodyRocket - 带有 json 主体的状态
【发布时间】:2021-06-05 21:29:52
【问题描述】:

我尝试在 Rust 的 Rocket 中返回带有错误的 json 正文。

pub fn error_status(error: Error) -> Status {
    match error {
        Error::NotFound => Status::NotFound,
        _ => Status::InternalServerError
    }
}

#[get("/user/<id>")]
pub fn get_user(id: i32, connection: DbConn) -> Result<Json<User>, Status> {

    UserService::show_user(id, &connection)
        .map(|u| Json(u))
        .map_err(|err| core::error_status(err))
}

当发生错误时,它返回Status::NotFound,但使用 html 正文,我需要 json 正文。 我尝试使用Return JSON with an HTTP status other than 200 in Rocket ,但没有成功。在该主题中,作者使用JsonValue 我需要Json(T) 作为动态json 正文。我无法成功创建响应:/ 我可以使用errorCatcher,但我不想在所有响应中都使用它,我只在api响应中需要json。

如何使用 json 正文返回错误? 提前谢谢你。

【问题讨论】:

  • 我尝试了与您链接的 solution 相同的方法,但将 Json 替换为 Json&lt;Thing&gt; 就可以了。
  • @rodrigo Json&lt;Thing&gt; 是来自 Thing 结构的显式 json 数据,我需要泛型类型 Json&lt;T&gt;
  • 类似thisApiResponse&lt;T&gt; 是通用的,但任何单个调用都会返回具体类型?
  • 是的,类似的东西,但使用泛型时,我在构建响应时遇到了问题。我稍后再试
  • 它有效,谢谢。我犯的错误是我将serde::Serialize 省略为泛型类型。

标签: rust response jsonresponse rust-rocket


【解决方案1】:

这是怎么做的

#![feature(proc_macro_hygiene)] 
#![feature(decl_macro)]

#[macro_use]
extern crate rocket;
#[macro_use]
extern crate rocket_contrib;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;

use rocket::http::{ContentType, Status};
use rocket::request::Request;
use rocket::response;
use rocket::response::{Responder, Response};
use rocket_contrib::json::{Json, JsonValue};

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Thing {
    pub name: String,
}

#[derive(Debug)]
struct ApiResponse<T> {
    json: Json<T>,
    status: Status,
}

impl<'r, T: serde::Serialize> Responder<'r> for ApiResponse<T> {
    fn respond_to(self, req: &Request) -> response::Result<'r> {
        Response::build_from(self.json.respond_to(&req).unwrap())
            .status(self.status)
            .header(ContentType::JSON)
            .ok()
    }
}

#[post("/create/thing", format = "application/json", data = "<thing>")]
fn put(thing: Json<Thing>) -> ApiResponse<Thing> {
    match thing.name.len() {
        0...3 => ApiResponse {
            json: thing,
            status: Status::UnprocessableEntity,
        },
        _ => ApiResponse {
            json: thing,
            status: Status::Ok,
        },
    }
}
fn main() {
    rocket::ignite().mount("/", routes![put]).launch();
} 

它甚至适用于0.5.0-rc.1

来源:本问题的 cmets 部分

【讨论】:

    猜你喜欢
    • 2021-09-19
    • 2019-07-18
    • 1970-01-01
    • 2019-03-08
    • 1970-01-01
    • 2018-10-21
    • 1970-01-01
    • 2017-07-10
    相关资源
    最近更新 更多