在 Rust Axum 中,我希望我的路由器处理程序接收多个标头。我可以接收这些标头作为结构,其中包含我期望的字段吗?

问题描述 投票:0回答:1

我希望在 GET 请求中收到这些标头:

Y 版本 Z型 Z-会话

我可以用这样的结构接收它们吗?

pub struct CustomHeaders {
    #[serde(rename = "Y-VERSION")]
    pub version: String,
    #[serde(rename = "Z-TYPE")]
    pub type: String,
    #[serde(rename = "Z-SESSION")]
    pub session: String
}

我尝试使用 TypedHeader,但它似乎不是我所期望的,因为我需要自定义标头。

我期望像 axum::extract::Query 这样的东西

示例:

pub async fn find_balance(
Path(account_string): Path<String>,
query_params: Query<QueryParams>, 

这是我现在与 HeaderMap 一起使用的函数的签名,用于仅提取授权标头:

#[debug_handler]
pub async fn find_balance(
    Path(balance_string): Path<String>,
    query_params: Query<QueryParams>,
    header_map: HeaderMap,
    JwtClaims(user): JwtClaims<RegisteredClaims>,
    State(client): State<Client>
) -> Result<Json<BalanceDTO>, Error> {
    let token = header_map.get(String::from("Authorization")).unwrap().to_str().unwrap();
    ...

如果可能的话,我想要一个使用 TypedHeader 的示例。

提前致谢!

rust http-headers rust-axum custom-headers axum
1个回答
0
投票

您可以使用

TypedHeader
来完成(在
axum-extra
中,不再在
axum
中)。由于您有三个标头,因此最好使用宏来创建它们,并且您可以使用
#[derive(FromRequestParts)]
:

将它们分组在一起
use axum::extract::FromRequestParts;
use axum::http::{HeaderName, HeaderValue};
use axum_extra::headers::{self, Header};
use axum_extra::TypedHeader;

macro_rules! declare_header {
    ( $name:expr => $struct:ident ) => {
        pub struct $struct(pub String);

        impl Header for $struct {
            fn name() -> &'static HeaderName {
                static NAME: HeaderName = HeaderName::from_static($name);
                &NAME
            }

            fn decode<'i, I>(values: &mut I) -> Result<Self, headers::Error>
            where
                Self: Sized,
                I: Iterator<Item = &'i HeaderValue>,
            {
                let value = values.next().ok_or_else(headers::Error::invalid)?;
                value
                    .to_str()
                    .map_err(|_| headers::Error::invalid())
                    .map(|value| Self(value.to_owned()))
            }

            fn encode<E: Extend<HeaderValue>>(&self, values: &mut E) {
                values.extend(std::iter::once(
                    HeaderValue::from_str(&self.0).expect("invalid header value"),
                ));
            }
        }
    };
}

declare_header!("y-version" => YVersion);
declare_header!("z-type" => ZType);
declare_header!("z-session" => ZSession);

#[derive(FromRequestParts)]
struct CustomHeaders {
    #[from_request(via(TypedHeader))]
    pub version: YVersion,
    #[from_request(via(TypedHeader))]
    pub r#type: ZType,
    #[from_request(via(TypedHeader))]
    pub session: ZSession,
}

然后使用

CustomHeaders
作为普通提取器(处理程序的参数)。

© www.soinside.com 2019 - 2024. All rights reserved.