如何在Rust的Axum后端中创建并传递Prisma连接至路由
问题
我正在用Prisma和Axum开发Rust后端,需要解决将数据库连接传递至路由的问题。目前已在main函数中创建Prisma客户端并传入routes模块分发至各路由,但接口返回空数组。我怀疑未将连接字符串传入客户端,但不确定是否为此原因;另外注意到prisma-client-rust示例有db.rs文件,但无法查看配置。我有含连接字符串的.env文件,但不知道如何传给客户端。
相关代码
main函数代码
#[tokio::main] async fn main() { let client = Arc::new(PrismaClient::_builder().build().await.unwrap()); //create_routes is in mod.rs below let app = create_routes(client); axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(app.into_make_service()) .await .unwrap(); }
模块代码(mod.rs)
use axum::{Router, routing::get, Extension}; use hello_world::hello_world; use handle_grades_get::handle_grades_get; use std::sync::Arc; use crate::PrismaClient; pub fn create_routes(client: Arc<PrismaClient>) -> Router<> { Router::new().route("/", get(hello_world)) .route("/getgrades", get(handle_grades_get)) .layer(Extension(client)) }
路由代码
use crate::{prisma::l_2_l_3_chemresult_02, PrismaClient}; use axum::{Extension, Json}; use std::sync::Arc; pub async fn handle_grades_get( Extension(client): Extension<Arc<PrismaClient>>, ) -> Json<Vec<l_2_l_3_chemresult_02::Data>> { let samples = client .l_2_l_3_chemresult_02() .find_many(vec![l_2_l_3_chemresult_02::heatid::equals(Some( "80".to_string(), ))]) .exec() .await .unwrap(); return Json(samples); }
排查与解决方案
1. 确保连接字符串正确传入Prisma客户端
prisma-client-rust默认读取项目根目录.env文件中的DATABASE_URL变量,但需确保以下两点:
- 你的
.env文件中确实存在DATABASE_URL变量,且值为正确的数据库连接字符串 - 显式加载
.env文件(避免因环境变量未加载导致客户端读取失败),修改main函数代码:
use dotenv::dotenv; use std::env; use std::sync::Arc; #[tokio::main] async fn main() { // 加载.env文件 dotenv().ok(); // 手动读取并传入连接字符串(也可省略此步,客户端会自动读取DATABASE_URL) let db_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set in .env"); let client = Arc::new( PrismaClient::_builder() .with_url(&db_url) .build() .await .unwrap() ); let app = create_routes(client); axum::Server::bind(&"0.0.0.0:3000".parse().unwrap()) .serve(app.into_make_service()) .await .unwrap(); }
2. 排查查询逻辑问题
接口返回空数组不一定是连接问题,也可能是查询条件无匹配数据:
- 暂时去掉
find_many中的条件,直接调用find_many(vec![]),验证是否能返回数据库中的数据 - 检查数据库中
l_2_l_3_chemresult_02表是否存在heatid为"80"的记录,注意字符串的大小写、空格等细节
3. 显式捕获客户端初始化错误
当前代码用unwrap()隐藏了错误信息,替换为错误处理可明确连接是否成功:
let client = match PrismaClient::_builder().build().await { Ok(client) => Arc::new(client), Err(e) => { eprintln!("Prisma客户端初始化失败: {}", e); std::process::exit(1); } };
4. 关于db.rs的配置参考
prisma-client-rust示例中的db.rs通常是封装客户端的单例初始化逻辑,示例如下:
use std::sync::Arc; use tokio::sync::OnceCell; use dotenv::dotenv; use crate::PrismaClient; static PRISMA_CLIENT: OnceCell<Arc<PrismaClient>> = OnceCell::const_new(); pub async fn get_client() -> Arc<PrismaClient> { PRISMA_CLIENT.get_or_init(|| async { dotenv().ok(); let client = PrismaClient::_builder().build().await.expect("Prisma客户端构建失败"); Arc::new(client) }).await.clone() }
使用这种方式可以在路由中直接调用get_client().await获取客户端,无需通过Extension传递,两种方式均可行。
内容的提问来源于stack exchange,提问作者Avi4nFLu
相关产品推荐
相关产品推荐

