如何解决如何在 Rocket.rs 中建立全局 postgres 池连接并使 FromRequest 自定义守卫异步?
我正在制作一个授权系统,它将实现来自 Web 框架火箭的 Fromrequest
特征,这是制作自定义防护所必需的。
我遇到的第一个问题是如何使连接全局化。我是否应该将其转换为常量,以便可以从实现中的函数访问它,或者火箭中是否存在缓存或某种形式的存储,可以访问 PgPool
连接(因为我使用的是 sqlx) & 可以进行查询。
我遇到的第二个问题是使 Fromrequest 函数异步。由于 sqlx 本身就是异步 afaik,我不知道 Rocket 是否还支持这一点。我正在考虑制作一个 tokio 线程,或者是否有 Rust 中的 .then()
版本,但我不知道
#[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(())
}
}
解决方法
在 0.5 版中对 Rocket 土地的异步支持。现在,您可以使用 master 分支: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:一个很好的代码示例,展示了这一点
https://github.com/samyak-jain/unagi:这个 repo 是我正在使用的一个应用程序,它使用 Rocket 的 master 分支,允许它使用异步。这个 repo 也为数据库连接做出了火箭贡献。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。