Skip to main content

AppState

Struct AppState 

Source
#[non_exhaustive]
pub struct AppState { pub pool: PgPool, pub schema_cache: RwLock<SchemaCache>, pub config: AppConfig, pub jwt_config: JwtConfig, pub jwt_cache: Option<JwtCache>, }
Expand description

Shared application state.

#[non_exhaustive] from 3.0.0: build one with AppState::new, then assign any field that should differ from what the configuration says.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§pool: PgPool

Database connection pool

§schema_cache: RwLock<SchemaCache>

Cached schema metadata

§config: AppConfig

Application configuration

§jwt_config: JwtConfig

JWT configuration

§jwt_cache: Option<JwtCache>

Cache of validated tokens, when jwt_cache_enabled asks for one.

Implementations§

Source§

impl AppState

Source

pub fn new( pool: PgPool, schema_cache: SchemaCache, config: AppConfig, ) -> Result<Self, JwtKeyError>

State for config, serving schema_cache through pool.

The JWT configuration and token cache are derived from config, as build derives them. Fails when the configured JWT secret does not parse; see postrust_engine::jwt_config. With PGRST_JWT_JWKS_URL set the keys are fetched when first needed, by the request that needs them; build also fetches them before serving, and keeps them fresh in the background.

Source

pub async fn schema_cache(&self) -> RwLockReadGuard<'_, SchemaCache>

Get a read lock on the schema cache.

Source

pub async fn reload_schema(&self) -> Result<(), Error>

Reload the schema cache. Used by the db_channel_enabled listener.

Source

pub fn default_schema(&self) -> &str

Get the default schema.

Source

pub fn schemas(&self) -> &[String]

Get exposed schemas.

Source

pub async fn begin_as( &self, user: &User, ) -> Result<Transaction<'static, Postgres>, Error>

A transaction on the pool that runs as user, as a REST request would: read-write, at the isolation level the configuration gives the role, with db_pre_request run. See AppState::begin_as_with.

Source

pub async fn begin_as_with( &self, user: &User, options: TxOptions, ) -> Result<Transaction<'static, Postgres>, Error>

A transaction on the pool that runs as user.

The pool is logged in as the authenticator, and a query sent on it runs as the authenticator: with every grant it has, and with no request.jwt.claims for a row-level security policy to read, so the policies written for the API’s roles do not apply. This makes the transaction the caller’s before you send anything on it. The same statements REST sends for a request, worked out by the same Session: SET TRANSACTION where one is asked for, the role, the claims, the facts about the request user carries, the search_path and app.settings.*, and db_pre_request.

Every one of them is local to the transaction. Commit it or drop it – a dropped one is rolled back – and the connection goes back to the pool as the authenticator, with nothing set.

What this does not do is make your handler untrusted code. It keeps what a request sends inside the policy: every statement you run with the caller’s values in it runs as the caller. But the handler runs as the authenticator, which may always switch back – RESET ROLE on the transaction is enough – and it holds the pool. Treat it as you would a SECURITY DEFINER function: code you wrote and reviewed, not something the client controls.

Fails as REST fails: a connection that cannot be had from the pool in time is logged at error and answered 500 (PGRST500), and a session the database refuses – a role that does not exist, a pre-request function that raises – is answered as the database’s error.

Trait Implementations§

Source§

impl State for AppState

Source§

type Db = Pool<Postgres>

The database requests run on.
Source§

type SchemaCache<'a> = RwLockReadGuard<'a, SchemaCache>

A borrow of the schema cache, held for as long as a request needs it.
Source§

fn db(&self) -> &PgPool

The database requests run on.
Source§

async fn schema_cache(&self) -> RwLockReadGuard<'_, SchemaCache>

The schema cache.
Source§

fn config(&self) -> &AppConfig

Configuration.
Source§

fn jwt_config(&self) -> &JwtConfig

How tokens are verified.
Source§

fn jwt_cache(&self) -> Option<&JwtCache>

The cache of verified tokens, where one is configured.
Source§

fn default_schema(&self) -> &str

The schema a request names when it names none.
Source§

fn schemas(&self) -> &[String]

The schemas the API exposes.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> MaybeSend for T
where T: Send + ?Sized,

Source§

impl<T> MaybeSendSync for T
where T: Send + Sync + ?Sized,

Source§

impl<T> MaybeSync for T
where T: Sync + ?Sized,

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more