pub struct GraphQLState {
pub pool: PgPool,
pub schema_cache: Arc<SchemaCache>,
pub generated_schema: GeneratedSchema,
pub schema: Schema,
pub role_schemas: HashMap<(String, bool), Schema>,
pub ungranted_schema: Option<Schema>,
pub config: SchemaConfig,
pub subscription_fields: Vec<SubscriptionField>,
pub broker: Arc<RwLock<Option<NotifyBroker>>>,
}Expand description
GraphQL execution state shared across requests.
Fields§
§pool: PgPoolDatabase connection pool
schema_cache: Arc<SchemaCache>Schema cache
generated_schema: GeneratedSchemaGenerated GraphQL schema
schema: Schemaasync-graphql Schema (built dynamically)
The unrestricted one: what an administrator is answered from, and what every caller is answered from on a server with no permission document.
role_schemas: HashMap<(String, bool), Schema>One schema per role the permission document names.
Hasura builds a schema per role because a permission is a statement
about what exists, not about what is allowed: a role with no select
on a table has no field to name, and naming one is a validation failure
rather than a denial. Each is built from a schema cache already reduced
to what that role may see.
Built at startup rather than on first use, so a permission document that cannot be built fails while someone is watching rather than on the first request from whichever role it broke.
Keyed by the role and by whether the caller asked for what only a
backend may name – which is a second schema rather than a check,
because backend_only decides whether a field exists.
ungranted_schema: Option<Schema>What a role the document never names is answered from.
Not a refusal. To Hasura an unrecognised role is a role with nothing
granted, so it gets a schema with nothing in it – and a request is
answered field 'user' not found in type: 'query_root', or no mutations exist where there is no mutation root at all, rather than
with a complaint about the role. address_permission_error sends
X-Hasura-Role: merchant, which no permission mentions, and expects
exactly that.
One schema for every such role rather than one each: they are all the same schema, since what they were granted is the same nothing.
config: SchemaConfigSchema configuration
subscription_fields: Vec<SubscriptionField>Subscription fields
broker: Arc<RwLock<Option<NotifyBroker>>>Notification broker for subscriptions
Implementations§
Source§impl GraphQLState
impl GraphQLState
Sourcepub fn new(
pool: PgPool,
schema_cache: Arc<SchemaCache>,
config: SchemaConfig,
) -> Result<Self, GraphQLError>
pub fn new( pool: PgPool, schema_cache: Arc<SchemaCache>, config: SchemaConfig, ) -> Result<Self, GraphQLError>
Create new GraphQL state from schema cache.
Sourcepub fn schema_for(&self, role: Option<&str>, backend: bool) -> Option<&Schema>
pub fn schema_for(&self, role: Option<&str>, backend: bool) -> Option<&Schema>
Which schema answers for a caller speaking as this role.
A role the document does not name is answered from the schema with nothing in it, which is Hasura’s reading: an unrecognised role is a role that was granted nothing, not an error. Three things are deliberately not that: a server with no permission document answers everyone from the unrestricted schema, an administrator is answered from it too – permissions are rules for everyone else – and so is a request on a server where the layer is off.
None only where the empty schema itself could not be built, which the
caller still turns into a refusal.
Sourcepub fn rebuild(&mut self) -> Result<(), GraphQLError>
pub fn rebuild(&mut self) -> Result<(), GraphQLError>
Rebuild the schema (e.g., after schema cache refresh).
Sourcepub async fn init_subscriptions(&self) -> Result<(), BrokerError>
pub async fn init_subscriptions(&self) -> Result<(), BrokerError>
Initialize the subscription broker.
This should be called after creating the state to enable subscriptions.
Sourcepub async fn stop_subscriptions(&self)
pub async fn stop_subscriptions(&self)
Stop the subscription broker.
Sourcepub async fn continue_subscriptions(
&mut self,
previous: Option<&GraphQLState>,
) -> Result<(), BrokerError>
pub async fn continue_subscriptions( &mut self, previous: Option<&GraphQLState>, ) -> Result<(), BrokerError>
Serve subscriptions on this state from previous’s broker, listening
on whatever channels this schema adds.
For a schema rebuilt under a running server. The broker carries over
rather than being replaced, so a subscription opened on the previous
schema keeps receiving notifications. With no broker yet – start-up
could not connect one, or there was no previous state – one is
started as init_subscriptions would.
Sourcepub async fn get_broker(&self) -> Option<Arc<RwLock<Option<NotifyBroker>>>>
pub async fn get_broker(&self) -> Option<Arc<RwLock<Option<NotifyBroker>>>>
Get the notification broker.
Auto Trait Implementations§
impl !RefUnwindSafe for GraphQLState
impl !UnwindSafe for GraphQLState
impl Freeze for GraphQLState
impl Send for GraphQLState
impl Sync for GraphQLState
impl Unpin for GraphQLState
impl UnsafeUnpin for GraphQLState
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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