微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何将 X-Total-Count 添加到 Rocket Rust REST API 中的标头响应?

如何解决如何将 X-Total-Count 添加到 Rocket Rust REST API 中的标头响应?

我使用 Rust 和 Rocket 创建了一个适用于 swagger 的 REST API。 现在我正在尝试使用 React react-admin 来使用这个 API,准确地说。一切正常,直到我需要调用出现著名的 X-Total-Count 问题的列表,但我无法解决它,可能是由于缺乏 Rust 的经验。

这是消息 "HTTP 响应中缺少 X-Total-Count 标头。jsonServer 数据提供程序希望资源列表的响应包含此标头以及构建分页的结果总数。如果您是使用 CORS,您是否在 Access-Control-Expose-Headers 标头中声明了 X-Total-Count”

这是我的响应头

HTTP/1.1 200 OK
Content-Type: application/json
Server: Rocket
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Expose-Headers: x-total-count,content-length,server
Content-Length: 45
Date: Wed,02 Jun 2021 04:38:21 GMT

我尝试了很多方法,在标题中附加 X-Total-Count: cant_registries 没有任何幸运

这是我的 main.rs。欢迎任何提示、帮助、修改。提前致谢

#![feature(proc_macro_hygiene,decl_macro)]

#[macro_use]
extern crate rocket;
#[macro_use]
extern crate rocket_okapi;

use rocket::request::Request;
use rocket::response::{self,Response,Responder};
use rocket::http::ContentType;
use rocket::http::Header;

use rocket::request::{Form,FromForm};
use rocket_contrib::json::Json;
use rocket_okapi::swagger_ui::*;
use schemars::JsonSchema;
use serde::{Deserialize,Serialize};

use rocket::http::Method;
use std::env;
use std::process::Command;
use rocket_cors::{
    AllowedOrigins,Cors,CorsOptions,};

#[derive(Serialize,Deserialize,JsonSchema)]
#[serde(rename_all = "camelCase")]
struct User {
    user_id: u64,username: String
}

// impl<'r> Responder<'r> for User {
//    fn respond_to(self,_: &Request) -> response::Result<'r> {
//        Response::build()
//            .header(Header::new("X-Total-Count","1"))
//            .ok()
//    }
// }

fn example_email() -> &'static str {
    "test@example.com"
}

fn make_cors() -> Cors {
    let allowed_origins = AllowedOrigins::some_exact(&[
        "http://localhost:3000",]);

    CorsOptions { // 5.
        allowed_origins,expose_headers: [ "x-total-count","content-length","server" ]
        .iter()
            .map(ToString::to_string)
            .collect(),allowed_methods: vec![Method::Get,Method::Post,Method::Patch].into_iter().map(From::from).collect(),allow_credentials: false,..Default::default()
    }
        .to_cors()
        .expect("error while building CORS")
}

/// # Get all users
#[openapi]
#[get("/user")]
fn get_all_users() -> Json<Vec<User>> {
    Json(vec![User {
        user_id: 88,username: "goja288".to_owned(),}])
    

}

fn main() {
    rocket::ignite()
        .mount(
            "/",routes_with_openapi![
                get_all_users,],)
        .mount(
            "/swagger-ui/",make_swagger_ui(&SwaggerUIConfig {
                url: "../openapi.json".to_owned(),..Default::default()
            }),).attach(make_cors())
        .launch();
}

解决方法

尝试通过使用自定义结构包装 Json<Vec<User>>(实现 Responder 特征)来向响应添加标头(请参阅 Rocket docs on custom responders

#[derive(Debug)]
struct JsonWithTotalCount<T: Serialize> {
    data: Json<Vec<T>>,total_count_header: Header<'static>,}

impl<T: Serialize> JsonWithTotalCount<T> {
    pub fn new(data: Vec<T>) -> Self {
        Self {
            total_count_header: Header::new("X-Total-Count",data.len().to_string()),data: Json(data),}
    }
}

impl<'r,T: Serialize> Responder<'r> for JsonWithTotalCount<T> {
    fn respond_to(self,request: &Request) -> response::Result<'r> {
        let mut build = Response::build();
        build.merge(self.data.respond_to(request)?);
        build.header(self.total_count_header);
        build.ok()
    }
}

并在您的 get_all_users 函数中使用它:

/// # Get all users
#[get("/user")]
fn get_all_users() -> JsonWithTotalCount<User> {
    JsonWithTotalCount::new(vec![User {
        user_id: 88,username: "goja288".to_owned(),}])
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。