我想要一个带有 Axum 的自定义响应类型,并将业务逻辑映射到 HTTP 响应,如下所示:
use axum::{
http::StatusCode,
response::{Html, IntoResponse},
Json,
};
use serde::Serialize;
// Response
pub enum Response<T = ()> {
Created,
NoContent,
JsonData(T),
HtmlData(T),
}
impl<T> IntoResponse for Response<T>
where
T: Serialize
{
fn into_response(self) -> axum::response::Response {
match self {
Self::Created => StatusCode::CREATED.into_response(),
Self::NoContent => StatusCode::OK.into_response(),
Self::JsonData(data) => (StatusCode::OK, Json(data)).into_response(),
Self::HtmlData(data) => (StatusCode::OK, Html(data)).into_response(),
}
}
}
然而,这并不管用。
no method named `into_response` found for tuple `(StatusCode, Html<T>)` in the current scope
method not found in `(StatusCode, Html<T>)
我想知道为什么不能像使用 Json 那样使用 Html。
问题在于和 的
IntoResponse
实现上有不同的特征界限,而 则接受任何实现:Html
Json
Json
Serialize
因为
Html
你必须传递一些实现Into<Body>
:axum
根本不知道如何为任意可序列化数据创建 html。您可以简单地将该特征添加到您的
impl IntoResponse
:您可能想要拆分类型参数,以便不对
JsonData
或HtmlData
类型强制执行不必要的特征界限。您可以采取的另一种方法是将案例中的数据包装
Html
在一个知道如何从任意可序列化数据构造主体的包装器中。并将数据包装在
into_response
: