如何在 Rocket Rust REST API 中将 X-Total-Count 添加到 header 响应?
How to add X-Total-Count to header response in Rocket Rust REST API?
我用 Rust 创建了一个 REST API 并且 Rocket 与 swagger 一起工作。
现在我正在尝试使用 React react-admin 来精确地使用这个 API。一切正常,直到我需要调用出现著名 X-Total-Count 问题的列表,但我无法解决它,可能是由于缺乏 Rust 经验。
这是消息
“HTTP 响应 中缺少 X-Total-Count header。jsonServer 数据提供程序期望资源列表的响应包含此 header 以及总计构建分页的结果数。如果您使用的是 CORS,您是否在 Access-Control-Expose-Headers header"
中声明了 X-Total-Count
这是我的回复header
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
我尝试了很多东西,在 header 中追加 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>>
将 header 添加到响应中(实现 Responder
trait) with a custom struct (see 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(),
}])
}
我用 Rust 创建了一个 REST API 并且 Rocket 与 swagger 一起工作。 现在我正在尝试使用 React react-admin 来精确地使用这个 API。一切正常,直到我需要调用出现著名 X-Total-Count 问题的列表,但我无法解决它,可能是由于缺乏 Rust 经验。
这是消息 “HTTP 响应 中缺少 X-Total-Count header。jsonServer 数据提供程序期望资源列表的响应包含此 header 以及总计构建分页的结果数。如果您使用的是 CORS,您是否在 Access-Control-Expose-Headers header"
中声明了 X-Total-Count这是我的回复header
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
我尝试了很多东西,在 header 中追加 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>>
将 header 添加到响应中(实现 Responder
trait) with a custom struct (see 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(),
}])
}