5 releases
1.0.3 |
|
---|---|
0.2.2 | Jan 12, 2024 |
0.1.1 | Jan 6, 2024 |
#1734 in Database interfaces
17KB
142 lines
axum-mongodb
axum-mongodb 是一个为 Axum Web 框架量身打造的库,旨在提供一种简洁且优雅的 MongoDB 集成方案。本库的设计灵感来源于著名的 JavaScript 框架 Nest.js,致力于简化并提升 Axum 项目中对 MongoDB 数据库的操作效率。
功能亮点
- 基于状态管理的数据库连接
- 便捷的 CRUD 操作封装
安装
在 Cargo.toml
中添加 axum-mongodb 依赖:
[dependencies]
axum-mongodb = "0.2.1"
或通过 cargo add
命令快速安装:
cargo add axum-mongodb
使用教程
1. 初始化数据库连接
在项目的入口点(如 lib.rs
)中使用 axum_mongodb::main
属性宏来设置 MongoDB 连接和初始化数据库服务。
use anyhow::Result;
use axum::{response::IntoResponse, routing::get, Router,Extension};
use axum_mongodb::preload::*;
use mongodb::{options::ClientOptions, Client};
use tokio::net::TcpListener;
// ...
#[axum_mongodb::main]
pub async fn start() -> Result<()> {
// 解析并创建 MongoDB 客户端配置
let client_options = ClientOptions::parse("mongodb://mongodb:password@localhost:21045/admin").await?;
let client = Client::with_options(client_options)?;
let db = client.database("todo");
// 创建 MongoDB 服务器状态实例
let mongodb_server = MongoDbServer::<Servers>::new(db).await;
// 构建 Axum 应用,并注入 MongoDB 状态到全局路由
let app = Router::new()
.route("/", get(hello_world))
.merge(todos_router())
// 注册State
.layer(Extension(mongodb_server));
// 启动服务器监听
let listener = TcpListener::bind("127.0.0.1:8080").await.unwrap();
tracing::info!("Listening on http://{}", listener.local_addr().unwrap());
axum::serve(listener, app).await.unwrap();
Ok(())
}
async fn hello_world() -> impl IntoResponse {
"hello world"
}
2. 定义数据模型
利用 axum_mongodb::Column
Derive 宏装饰你的结构体以支持与 MongoDB 的交互:
use anyhow::Result;
use axum_mongodb::futures::TryStreamExt;
use bson::{self, doc, oid::ObjectId};
use mongodb::{results::{DeleteResult, InsertOneResult, UpdateResult},};
use serde::{Deserialize, Serialize};
#[derive(Debug, Column, Deserialize, Serialize, Clone)]
pub struct Todo {
#[serde(
serialize_with = "bson::serde_helpers::serialize_object_id_as_hex_string",
rename = "_id"
)]
id: ObjectId,
description: String,
completed: bool,
create_time: chrono::DateTime<chrono::Local>,
update_time: chrono::Local,
}
impl Server<Todo> {
pub async fn create_todo(&self, description: String) -> Result<InsertOneResult> {
Ok(self
.insert_one(
Todo {
id: ObjectId::new(),
description,
completed: false,
create_time: chrono::Local::now(),
update_time: chrono::Local::now(),
},
None,
)
.await?)
}
// ... 其他CRUD方法实现
}
3. 在 Axum handler 中使用
在处理函数中注入 Server<Todo>
实例,并调用相应的方法完成数据库操作:
use axum::{extract::Path, response::IntoResponse, Json};
use serde::Deserialize;
use super::Todo;
use crate::Server;
#[derive(Debug, Deserialize)]
pub struct TodoQuery {
pub description: String,
pub completed: Option<bool>,
}
pub async fn create_todo(todo: Server<Todo>, Json(TodoQuery { description, .. }): Json<TodoQuery>) -> impl IntoResponse {
let res = todo.create_todo(description).await.unwrap();
Json(res)
}
4. 注册路由
定义并组合相关路由,将 MongoDB 服务状态注入到路由模块中:
mod controller;
use controller::{create_todo, delete_todo, get_todo, get_todos, update_todo};
use axum::{
routing::{get, post},
Router,
};
pub use server::Todo;
pub fn todos_router() -> Router{
Router::new()
.route("/todos", post(create_todo).get(get_todos))
.route("/todos/:id", get(get_todo).put(update_todo).delete(delete_todo))
}
示例代码与文档
完整的示例代码可参考 axum-mongodb-example。同时,你可以查阅 API 文档 以获得更详细的信息和示例说明。
更多信息
请访问项目主页或查看仓库中的文档以获取更多关于如何在您的 Axum 项目中高效地集成和使用 MongoDB 的细节及高级功能。
Dependencies
~28–40MB
~730K SLoC