graphql-engine-1.0.0: GraphQL API over Postgres
Safe HaskellNone
LanguageHaskell2010

Hasura.GraphQL.Schema

Synopsis

Documentation

buildGQLContext :: forall m. (MonadError QErr m, MonadIO m) => ServerConfigCtx -> GraphQLQueryType -> SourceCache -> HashMap RemoteSchemaName (RemoteSchemaCtx, MetadataObject) -> ActionCache -> AnnotatedCustomTypes -> m (SchemaIntrospection, HashMap RoleName (RoleContext GQLContext), GQLContext, HashSet InconsistentMetadata) Source #

Builds the full GraphQL context for a given query type.

A GQLContext stores how an incoming request should be processed: how to translate each incoming field of a request into a corresponding semantic representation. There is a different one per Role, as each role might have different permissions, and therefore not access to the same set of objects in the schema.

This function takes all necessary information from the metadata, and the GraphQLQueryType, and builds all relevant contexts: a hash map from RoleName to their GQLContext and the "default" context for unauthenticated users.

When building the schema for each role, we treat the remote schemas as "second-class citizens" compared to sources; more specifically, we attempt to detect whether the inclusion of a given remote schema would result in root fields conflict, and only keep schemas that don't generate any. This results in a partial schema being available to the users, and a better error message than would arise from safeSelectionSet.

unauthenticatedContext :: forall m. (MonadError QErr m, MonadIO m) => HashMap RemoteSchemaName (RemoteSchemaCtx, MetadataObject) -> RemoteSchemaPermissions -> m (GQLContext, HashSet InconsistentMetadata) Source #

Builds the schema context for unauthenticated users.

This context is used whenever the user queries the engine with a role that is unknown, and therefore not present in the context map. Before remote schema permissions were introduced, remotes were considered to be a public entity, and we therefore allowed an unknown role also to query the remotes. To maintain backwards compatibility, we check if remote schema permissions are enabled; remote schemas will only be available to unauthenticated users if permissions aren't enabled.

buildQueryAndSubscriptionFields :: forall b r m n. MonadBuildSchema b r m n => MkRootFieldName -> SourceInfo b -> TableCache b -> FunctionCache b -> m ([FieldParser n (QueryRootField UnpreparedValue)], [FieldParser n (SubscriptionRootField UnpreparedValue)], [(Name, Parser 'Output n (ApolloFederationParserFunction n))]) Source #

buildQueryAndSubscriptionFields builds the query and the subscription fields of the tables tracked in the source. The query root fields and the subscription root fields may not be equal because a root field may be enabled in the query_root_field and not in the subscription_root_field, so a tuple of array of field parsers corresponding to query field parsers and subscription field parsers.

parseBuildIntrospectionSchema :: MonadParse m => Type 'Output -> Maybe (Type 'Output) -> Maybe (Type 'Output) -> m Schema Source #

Builds a Schema at query parsing time

buildSubscriptionParser :: forall n m. (MonadMemoize m, MonadError QErr m, MonadParse n) => [FieldParser n (NamespacedField (QueryRootField UnpreparedValue))] -> [FieldParser n (NamespacedField (RemoteSchemaRootField (RemoteRelationshipField UnpreparedValue) RemoteSchemaVariable))] -> [FieldParser n (QueryRootField UnpreparedValue)] -> m (Maybe (Parser 'Output n (RootFieldMap (QueryRootField UnpreparedValue)))) Source #

Prepare the parser for subscriptions. Every postgres query field is exposed as a subscription along with fields to get the status of asynchronous actions.

safeSelectionSet :: forall n m a. (QErrM n, MonadParse m) => Name -> Maybe Description -> [FieldParser m a] -> n (Parser 'Output m (InsOrdHashMap Name (ParsedSelection a))) Source #

Calls safeSelectionSet, and rethrows any error as a QErr.

customizeFields :: forall f n db remote action. (Functor f, MonadParse n) => SourceCustomization -> MkTypename -> f [FieldParser n (RootField db remote action Value)] -> f [FieldParser n (NamespacedField (RootField db remote action Value))] Source #

Apply a source's customization options to a list of its fields.

mkRootField :: forall b n a db remote action raw. (HasTag b, Functor n) => SourceName -> SourceConfig b -> Maybe QueryTagsConfig -> (a -> db b) -> FieldParser n a -> FieldParser n (RootField db remote action raw) Source #

All the BackendSchema methods produce something of the form m [FieldParser n a], where a is something specific to what is being parsed by the given method.

In order to build the complete schema these must be homogenised and be annotated with query-tag data, which this function makes easy. This function converts a single field parser. mkRootFields transforms a list of field parsers.

mkRootFields :: forall b m n a db remote action raw. (HasTag b, Functor m, Functor n) => SourceName -> SourceConfig b -> Maybe QueryTagsConfig -> (a -> db b) -> m [FieldParser n a] -> m [FieldParser n (RootField db remote action raw)] Source #

mkRootFields is mkRootField applied on a list of FieldParser.

typenameToRawRF :: ParsedSelection (RootField db remote action Value) -> RootField db remote action Value Source #