如何使 axum 路由器句柄返回不同的内容类型响应?

Pro*_*ter 7 hyper rust-axum

例如,当用户访问时http://127.0.0.1:8080/hello,如果查询参数id为1,则返回纯文本响应。如果id是2,给出一个json结构。

概括:

id(输入) 状态码 内容类型 身体
1 200 应用程序/json {“名称”:“世界”}
2 400 文本/纯文本 没有这样的人
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));

Run Code Online (Sandbox Code Playgroud)

d27*_*718 7

查看本模块开头的示例response。Axum 为您提供了多种返回数据的不同方法,以便自动适当地设置 Content-type 标头。

(这对我来说似乎是一个家庭作业问题,所以我不会准确地为你编写你的函数。)

例如,如果您返回 aString作为正文,则 Content-type 将自动设置为“text/plain”:

use axum::response::{IntoResponse, Response};

async fn returns_string() -> Response {
    String::from("Hello, world!").into_response()
}
Run Code Online (Sandbox Code Playgroud)

还有一个自定义Json结构,用于以 JSON 形式返回任何实现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()
}
Run Code Online (Sandbox Code Playgroud)

因此,我们可以编写一个函数,该函数可以根据请求的某些属性返回任一类型的响应。让我们根据“Accept”标头的值进行选择:

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(),
    }
}

Run Code Online (Sandbox Code Playgroud)

  • 您可以将其编辑到您的_问题_中以便可以理解吗? (2认同)