首页 > 解决方案 > 在请求保护中访问 Rocket 0.4 数据库连接池

问题描述

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

fn get_data(conn: db::MyDatabasePool) -> MyModel {
    MyModel::get(&conn)
}

但是,在 impl 块中,FromRequest我不能只将conn参数添加到函数的参数列表中from_request。如何在请求保护之外访问我的连接池?

标签: rustrust-dieselrust-rocket

解决方案


数据库状态的火箭指南说:

每当需要连接到数据库时,使用您的 [database pool] 类型作为请求保护

由于可以通过创建数据库池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))
    }
}

推荐阅读