For example, when user access http://127.0.0.1:8080/hello
, if query parameter id
is 1, a plain text response return. If id
is 2, give a JSON structure.
Summary:
id (input) | status code | content-type | body |
---|---|---|---|
1 | 200 | application/json | {"name": "world"} |
2 | 400 | text/plain | no such person |
struct HelloParam {
id: u16,
}
struct HelloResponse {
name: String,
}
async fn hello_get(Query(params): Query<HelloParam>) -> Response {
// how to implement it?
}
let router = Router::new().route("/hello", get(hello_get));
Check out the examples at the beginning of the response
module. Axum gives you a bevvy of different ways to return data so that the Content-type header is automatically set appropriately.
(This seems like a homework question to me, so I'm not going to write your function for you exactly.)
For example, if you return a String
as a body, the Content-type will automatically be set to "text/plain":
use axum::response::{IntoResponse, Response};
async fn returns_string() -> Response {
String::from("Hello, world!").into_response()
}
There is also a custom Json
struct for returning as JSON (with the Content-type header set appropriately) any type that implements serde::Serialize
.
use axum::response::{Json, IntoResponse, Response};
use serde::Serialize;
#[derive(Serialize)]
struct Hello {
name: String,
}
async fn returns_json() -> Response {
let hello = Hello {
name: String::from("world"),
};
Json(hello).into_response()
}
So we can write a function that could return either type of response based on some property of the request. Let's choose based on the value of the "Accept" header:
use axum::{
http::{
header::{ACCEPT, HeaderMap},
status::StatusCode,
},
response::{Json, IntoResponse, Response},
};
use serde::Serialize;
#[derive(Serialize)]
struct Hello {
name: String,
}
async fn heterogeneous_handle(headers: HeaderMap) -> Response {
match headers.get(ACCEPT).map(|x| x.as_bytes()) {
Some(b"text/plain") =>
String::from("Hello, world!").into_response(),
Some(b"application/json") => {
let hello = Hello {
name: String::from("world"),
};
Json(hello).into_response()
},
_ => StatusCode::BAD_REQUEST.into_response(),
}
}