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

Hasura.GraphQL.Execute.RemoteJoin.RemoteSchema

Description

How to construct and execute a call to a remote schema for a remote join.

There are three steps required to do this: 1. construct the call: given the requested fields, the phantom fields, the values extracted by the LHS, construct a GraphQL query 2. execute that GraphQL query over the network 3. build a index of the variables out of the response

This can be done as one function, but we also export the individual steps for debugging / test purposes. We congregate all intermediary state in the opaque RemoteSchemaCall type.

Synopsis

Documentation

makeRemoteSchemaJoinCall Source #

Arguments

:: MonadError QErr m 
=> (GQLReqOutgoing -> m ByteString)

Function to send a request over the network.

-> UserInfo

User information.

-> RemoteSchemaJoin

Information about that remote join.

-> IntMap JoinArgument

Mapping from JoinArgumentId to its corresponding JoinArgument.

-> m (Maybe (IntMap Value))

The resulting join index (see buildJoinIndex) if any.

Construct and execute a call to a remote schema for a remote join.

data RemoteSchemaCall Source #

Intermediate type containing all of the information required to perform a remote schema call, constructed from the static join information.

newtype ResponsePath Source #

Used to extract the value from a remote schema response.

For example: if a remote relationship is defined to retrieve data from some deeply nested field, this is the path towards that deeply nested field.

Constructors

ResponsePath (NonEmpty Name) 

buildRemoteSchemaCall :: MonadError QErr m => RemoteSchemaJoin -> IntMap JoinArgument -> UserInfo -> m (Maybe RemoteSchemaCall) Source #

Constructs a RemoteSchemaCall from some static information, such as the definition of the join, and dynamic information such as the user's information and the map of join arguments.

fieldCallsToField Source #

Arguments

:: forall m. MonadError QErr m 
=> HashMap Name (InputValue RemoteSchemaVariable)

user input arguments to the remote join field

-> HashMap Name (Value Void)

Contains the values of the variables that have been defined in the remote join definition

-> SelectionSet NoFragments RemoteSchemaVariable

Inserted at leaf of nested FieldCalls

-> Name

Top-level name to set for this Field

-> NonEmpty FieldCall 
-> m (Field NoFragments RemoteSchemaVariable) 

Fold nested FieldCalls into a bare Field, inserting the passed selection set at the leaf of the tree we construct.

createArguments :: MonadError QErr m => HashMap Name (Value Void) -> RemoteArguments -> m (HashMap Name (Value Void)) Source #

Create an argument map using the inputs taken from the left hand side.

combineValues :: MonadError QErr m => Name -> Value RemoteSchemaVariable -> Value RemoteSchemaVariable -> m (Value RemoteSchemaVariable) Source #

Combine two GraphQL values together.

This is used to combine different input arguments into one. This function can only combine objects or lists pairwise, and fails if it has to combine any other combination of values.

>>> combineValues (Object (fromList [("id", Number 1)]) (Object (fromList [("name", String "foo")])
Object (fromList [("id", Number 1), ("name", String "foo")])

fieldsToRequest :: NonEmpty (Field NoFragments Variable) -> GQLReqOutgoing Source #

Craft a GraphQL query document from the list of fields.

executeRemoteSchemaCall Source #

Arguments

:: MonadError QErr m 
=> (GQLReqOutgoing -> m ByteString)

Function to send a request over the network.

-> RemoteSchemaCall

Information about that call.

-> m Object

Resulting JSON object

Sends the call over the network, and parse the resulting ByteString.

buildJoinIndex :: forall m. MonadError QErr m => RemoteSchemaCall -> Object -> m (IntMap Value) Source #

Construct a join index from the remote source's Value response.

This function extracts from the RemoteJoinCall a mapping from JoinArgumentId to ResponsePath: from an integer that uniquely identifies a join argument to the "path" at which we expect that value in the response. With it, and with the actual reponse JSON value obtained from the remote server, it constructs a corresponding mapping of, for each argument, its extracted value.

If the response does not have value at any of the provided ResponsePaths, throw a generic QErr.

NOTE(jkachmar): If we switch to an Applicative validator, we can collect more than one missing ResponsePaths (rather than short-circuiting on the first missing value).

parseGraphQLName :: MonadError QErr m => Text -> m Name Source #