在本文中,我们将全面了解如何使用 Axum 编写 Web 服务。这也将包括0.7 的更改。
1、路由
Axum 遵循 REST 风格的 API(例如 Express)的风格,您可以在其中创建处理函数并将它们附加到 axum 的axum::Router类型。
async fn hello_world() -> &'static str { "Hello world!" }
|
然后我们可以将它添加到我们的路由器中,如下所示:
use axum::{Router, routing::get};
fn init_router() -> Router { Router::new() .route("/", get(hello_world)) }
|
要使处理函数有效,它必须是 axum::response::Response 类型或实现 axum::response::IntoResponse。
大多数原始类型和所有 Axum 自己的类型都已实现了这一点--例如,如果我们想向用户发送一些 JSON 数据,我们可以使用 Axum 的 JSON 类型来轻松实现,方法是使用它作为返回类型,并用 axum::Json 类型封装我们要发送的任何内容。
如上所示,我们还可以单独返回一个字符串(片段)。
我们还可以直接使用 impl IntoResponse,乍一看,这立即解决了我们需要确定返回类型的问题;但是,直接使用它也意味着要确保所有返回类型都是相同的!这意味着我们可能会遇到不必要的错误。相反,我们可以为一个枚举或结构体实现 IntoResponse,然后将其用作返回类型。请参见下文:
use axum::{response::{Response, IntoResponse}, Json};
// 在这里,我们展示了一个实现序列化 + 发送的类型 #[derive(Serialize)] struct Message { message: String }
enum ApiResponse { Ok, Created, JsonData(Vec<Message>), }
impl IntoResponse for ApiResponse { fn into_response(&self) -> Response { match self { Response::OK => (StatusCode::OK).into_response(), Response::Created => (StatusCode::CREATED).into_response(), Response::JsonData(data) => (StatusCode::OK, Json(data)).into_response() } } }
|
然后,您可以在处理函数中这样实现枚举:
async fn my_function() -> ApiResponse { // ... rest of your code }
|
当然,我们也可以为返回使用结果类型!虽然从技术上讲,错误类型也可以接受任何可以转化为 HTTP 响应的内容,但我们也可以实现一种错误类型,以说明 HTTP 请求在应用程序中失败的几种不同方式,就像我们在成功 HTTP 请求枚举中所做的那样。请看下面:
enum ApiError { BadRequest, Forbidden, Unauthorised, InternalServerError }
// ... 在这里实现 IntoResponse
async fn my_function() -> Result<ApiResponse, ApiError> { // ... your code }
|
这样,我们在编写 Axum 路由时就能区分错误和成功请求。
2、在 Axum 中添加数据库
通常,在设置数据库时,您可能需要设置数据库连接:
use axum::{Router, Extension}; use sqlx::PgPoolOptions;
#[tokio::main] async fn main() { let dbconnection = PgPoolOptions::new() .max_connections(5) .connect(<db-connection-string-here>).await;
let router = Router::new().route("/", get(hello_world)).layer(Extension::new(dbconnection));
//... rest of your code }
|
然后,您需要配置自己的 Postgres 实例,无论是安装在本地计算机上,还是通过 Docker 或其他方式配置。