Mapping response based on query parameter #1456
-
I am working on implementing a server for an API that returns JSON if there is an What would be the best way to implement this in a way that has no impact on route handler implementations? Currently my route handlers return a tuple containing both the I looked at the new It's not a huge deal, but I was just curious to how something like this might be implemented. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
You can do something like this use axum::{
async_trait,
extract::{FromRequestParts, Query},
http::request::Parts,
response::Response,
};
use serde::{Deserialize, Serialize};
async fn handler(format: Format) -> Response {
#[derive(Serialize)]
struct Data {
value: String,
}
format.render(Data {
value: "foo".to_owned(),
})
}
enum Format {
Json,
Xml,
}
impl Format {
fn render<T>(self, data: T) -> Response
where
T: Serialize,
{
match self {
Format::Json => {
todo!("render json...")
}
Format::Xml => {
todo!("render xml...")
}
}
}
}
#[async_trait]
impl<S> FromRequestParts<S> for Format
where
S: Send + Sync,
{
type Rejection = std::convert::Infallible;
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
#[derive(Deserialize)]
struct FormatQuery {
f: String,
}
let Query(query) = match Query::<FormatQuery>::from_request_parts(parts, state).await {
Ok(query) => query,
Err(_) => return Ok(Self::Xml),
};
if query.f == "json" {
Ok(Self::Json)
} else {
Ok(Self::Xml)
}
}
} |
Beta Was this translation helpful? Give feedback.
You can do something like this