在请求防护中访问Rocket 0.4数据库连接池

时间:2019-03-16 17:38:04

标签: rust rust-diesel rust-rocket

我正在使用Rocket创建带有身份验证的Web应用。为此,我创建了一个实现User的{​​{1}}结构。它使用授权标头,其中包含JSON Web令牌。我反序列化此令牌以获得有效负载,然后从数据库查询用户。这意味着FromRequest实现需要一个FromRequest。在Rocket 0.3中,这意味着调用diesel::PgConnection,但是在Rocket 0.4中,我们可以访问连接池。通常,我将按以下方式访问此连接池:

PgConnection::establish

但是,在fn get_data(conn: db::MyDatabasePool) -> MyModel { MyModel::get(&conn) } 的impl块中,我不能仅将FromRequest自变量添加到conn函数的自变量列表中。如何在请求保护程序之外访问我的连接池?

1 个答案:

答案 0 :(得分:1)

火箭guide for database state说:

  

每当需要与数据库建立连接时,请使用您的[数据库池]类型作为请求防护

由于可以通过FromRequest创建数据库池,并且您正在实现FromRequest,因此可以通过DbPool::from_request(request)使用现有的实现:

use rocket::{
    request::{self, FromRequest, Request},
    Outcome,
};

// =====
// This is a dummy implementation of a pool
// Refer to the Rocket guides for the correct way to do this
struct DbPool;

impl<'a, 'r> FromRequest<'a, 'r> for DbPool {
    type Error = &'static str;

    fn from_request(_: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
        Outcome::Success(Self)
    }
}
// =====

struct MyDbType;

impl MyDbType {
    fn from_db(_: &DbPool) -> Self {
        Self
    }
}

impl<'a, 'r> FromRequest<'a, 'r> for MyDbType {
    type Error = &'static str;

    fn from_request(request: &'a Request<'r>) -> request::Outcome<Self, Self::Error> {
        let pool = DbPool::from_request(request);
        pool.map(|pool| MyDbType::from_db(&pool))
    }
}