I am creating a webapp with authentication using Rocket. To do this, I created a User
struct that implements FromRequest
. It takes the authorization header, which contains a JSON Web Token. I deserialize this token to obtain the payload, and then I query the user from the database. This means that the FromRequest
implementation needs a diesel::PgConnection
. In Rocket 0.3 this meant calling PgConnection::establish
, but with Rocket 0.4 we have access to a connection pool. Normally I would access this connection pool as follows:
fn get_data(conn: db::MyDatabasePool) -> MyModel {
MyModel::get(&conn)
}
However, within the impl block for FromRequest
I can not just add the conn
argument to the argument list of from_request
function. How do I access my connection pool outside of a request guard?
The Rocket guide for database state says:
Whenever a connection to the database is needed, use your [database pool] type as a request guard
Since a database pool can be created via FromRequest
and you are implementing FromRequest
, use the existing implementation via 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))
}
}