如何使postgres池连接在火箭全局.rs和使FromRequest自定义守卫asyncable?



我正在制作一个授权系统,该系统将实现web框架火箭的FromRequest特性,这是制作自定义警卫所需的。

我要讨论的第一个问题是如何使连接全局。我是否应该将其转换为常量,以便可以从实现中的函数访问,或者在火箭或某种形式的存储中缓存PgPool连接(因为我使用sqlx)可以访问&可以进行查询

我经历的第二个问题是使FromRequest函数异步。由于sqlx本身就是异步的,我不知道rocket是否已经支持这个功能。我在想要么做一个东京线程,或者如果有一个版本的.then()在Rust,但我不知道

#[derive(Debug)]
struct User {
username: String,
password: String,
user_id: i16,
phone_number: String,
display_name: String,
//other fields omitted
}
impl<'a, 'r> FromRequest<'a, 'r> for &'a User {
type Error = !;
fn from_request(request: &'a Request<'r>) -> request::Outcome<&'a User, !> {
let user_result = request.local_cache(|| {
//..need to fetch user with sqlx [but sqlx is async]
//and later get cookies and check
}); 
user_result.as_ref().or_forward(())
}
}

Rocket lands在0.5版的异步支持。现在,您可以使用主分支:https://github.com/SergioBenitez/Rocket

在Rocket中处理这个用例的惯用方法是为数据库使用Rocket -contrib适配器:https://docs.rs/rocket_contrib/0.4.7/rocket_contrib/databases/index.html#provided

您需要为数据库实现Poolable Trait。以下是相关文档:https://docs.rs/rocket_contrib/0.4.7/rocket_contrib/databases/trait.Poolable.html

Rocket已经提供了以下特性:

diesel::MysqlConnection
diesel::PgConnection
diesel::SqliteConnection
postgres::Connection
mysql::Conn
rusqlite::Connection
rusted_cypher::GraphClient
redis::Connection

你可以这样使用数据库宏:

use rocket_contrib::databases::postgres;
#[database("db_name")]
struct MyPgDatabase(postgres::Connection);
fn main() {
rocket::custom(config)
.attach(MyPgDatabase::fairing())
.launch();
}

您可以使用此类型作为请求保护,然后检索数据库连接,因为上面的宏会自动为您生成FromRequest实现

#[get("/")]
fn my_handler(conn: MyPgDatabase) {
// ...
}

宏还生成一个Deref实现,允许您访问内部连接类型。

参考:
https://github.com/TatriX/realworld-rust-rocket:一个很好的代码示例,显示了这个

最新更新