Safe Haskell | None |
---|---|
Language | Haskell2010 |
Representation for queries going to remote schemas. Due to the existence of remote relationships from remote schemas, we can't simply reuse the GraphQL document AST we define in graphql-parser-hs, and instead redefine a custom structure to represent such queries.
Synopsis
- data SelectionSet r var
- = SelectionSetObject (ObjectSelectionSet r var)
- | SelectionSetUnion (DeduplicatedSelectionSet r var)
- | SelectionSetInterface (DeduplicatedSelectionSet r var)
- | SelectionSetNone
- data DeduplicatedSelectionSet r var = DeduplicatedSelectionSet {
- _dssCommonFields :: HashSet Name
- _dssMemberSelectionSets :: HashMap Name (ObjectSelectionSet r var)
- type ObjectSelectionSet r var = InsOrdHashMap Name (Field r var)
- mkInterfaceSelectionSet :: HashSet Name -> [(Name, ObjectSelectionSet r var)] -> DeduplicatedSelectionSet r var
- mkUnionSelectionSet :: [(Name, ObjectSelectionSet r var)] -> DeduplicatedSelectionSet r var
- data Field r var
- = FieldGraphQL (GraphQLField r var)
- | FieldRemote (SchemaRemoteRelationshipSelect r)
- data GraphQLField r var = GraphQLField {
- _fAlias :: Name
- _fName :: Name
- _fArguments :: HashMap Name (Value var)
- _fDirectives :: [Directive var]
- _fSelectionSet :: SelectionSet r var
- mkGraphQLField :: Maybe Name -> Name -> HashMap Name (Value var) -> [Directive var] -> SelectionSet r var -> GraphQLField r var
- data RemoteSchemaRootField r var = RemoteSchemaRootField {}
- data SchemaRemoteRelationshipSelect r = SchemaRemoteRelationshipSelect {
- _srrsLHSJoinFields :: HashMap FieldName Name
- _srrsRelationship :: r
- data RemoteFieldArgument = RemoteFieldArgument {
- _rfaArgument :: Name
- _rfaValue :: InputValue RemoteSchemaVariable
- data RemoteSchemaSelect r = RemoteSchemaSelect {}
- convertSelectionSet :: forall var. Eq var => SelectionSet Void var -> SelectionSet NoFragments var
- convertGraphQLField :: Eq var => GraphQLField Void var -> Field NoFragments var
- reduceAbstractTypeSelectionSet :: Eq var => DeduplicatedSelectionSet Void var -> (ObjectSelectionSet Void var, HashMap Name (ObjectSelectionSet Void var))
- _FieldRemote :: forall r var. Prism' (Field r var) (SchemaRemoteRelationshipSelect r)
- _FieldGraphQL :: forall r var var. Prism (Field r var) (Field r var) (GraphQLField r var) (GraphQLField r var)
- fSelectionSet :: forall r var r. Lens (GraphQLField r var) (GraphQLField r var) (SelectionSet r var) (SelectionSet r var)
- fName :: forall r var. Lens' (GraphQLField r var) Name
- fDirectives :: forall r var. Lens' (GraphQLField r var) [Directive var]
- fArguments :: forall r var. Lens' (GraphQLField r var) (HashMap Name (Value var))
- fAlias :: forall r var. Lens' (GraphQLField r var) Name
- dssMemberSelectionSets :: forall r var r var. Lens (DeduplicatedSelectionSet r var) (DeduplicatedSelectionSet r var) (HashMap Name (ObjectSelectionSet r var)) (HashMap Name (ObjectSelectionSet r var))
- dssCommonFields :: forall r var. Lens' (DeduplicatedSelectionSet r var) (HashSet Name)
Documentation
data SelectionSet r var Source #
Custom representation of a selection set.
Similarly to other parts of the IR, the r
argument is used for remote
relationships.
SelectionSetObject (ObjectSelectionSet r var) | |
SelectionSetUnion (DeduplicatedSelectionSet r var) | |
SelectionSetInterface (DeduplicatedSelectionSet r var) | |
SelectionSetNone |
Instances
data DeduplicatedSelectionSet r var Source #
Representation of the normalized selection set of an interface/union type.
This representation is used to attempt to minimize the size of the GraphQL query that eventually gets sent to the GraphQL server by defining as many fields as possible on the abstract type.
DeduplicatedSelectionSet | |
|
Instances
type ObjectSelectionSet r var = InsOrdHashMap Name (Field r var) Source #
mkInterfaceSelectionSet Source #
:: HashSet Name | Member fields of the interface |
-> [(Name, ObjectSelectionSet r var)] | Selection sets for all the member types |
-> DeduplicatedSelectionSet r var |
Constructs an InterfaceSelectionSet
from a set of interface fields and an
association list of the fields. This function ensures that __typename
is
present in the set of interface fields.
:: [(Name, ObjectSelectionSet r var)] | Selection sets for all the member types |
-> DeduplicatedSelectionSet r var |
Constructs an UnionSelectionSet
from a list of the fields, using a
singleton set of __typename
for the set of common fields.
Representation of one individual field.
This particular type is the reason why we need a different representation from the one in 'graphql-parser-hs': we differentiate between selection fields that target the actual remote schema, and fields that, instead, are remote from it and need to be treated differently.
Instances
Functor (Field r) Source # | |
Foldable (Field r) Source # | |
Defined in Hasura.RQL.IR.RemoteSchema fold :: Monoid m => Field r m -> m # foldMap :: Monoid m => (a -> m) -> Field r a -> m # foldMap' :: Monoid m => (a -> m) -> Field r a -> m # foldr :: (a -> b -> b) -> b -> Field r a -> b # foldr' :: (a -> b -> b) -> b -> Field r a -> b # foldl :: (b -> a -> b) -> b -> Field r a -> b # foldl' :: (b -> a -> b) -> b -> Field r a -> b # foldr1 :: (a -> a -> a) -> Field r a -> a # foldl1 :: (a -> a -> a) -> Field r a -> a # elem :: Eq a => a -> Field r a -> Bool # maximum :: Ord a => Field r a -> a # minimum :: Ord a => Field r a -> a # | |
Traversable (Field r) Source # | |
(Eq var, Eq r) => Eq (Field r var) Source # | |
(Show var, Show r) => Show (Field r var) Source # | |
data GraphQLField r var Source #
Normalized representation of a GraphQL field.
This type is almost identical to Field
, except for the fact that the
selection set is our annotated SelectionSet
, instead of the original
SelectionSet
. We use this type to represent the fields of a selection
that do target the remote schema.
GraphQLField | |
|
Instances
mkGraphQLField :: Maybe Name -> Name -> HashMap Name (Value var) -> [Directive var] -> SelectionSet r var -> GraphQLField r var Source #
data RemoteSchemaRootField r var Source #
Root entry point for a remote schema.
Instances
data SchemaRemoteRelationshipSelect r Source #
A remote relationship's selection and fields required for its join condition.
SchemaRemoteRelationshipSelect | |
|
Instances
data RemoteFieldArgument Source #
Instances
Eq RemoteFieldArgument Source # | |
Defined in Hasura.RQL.IR.RemoteSchema (==) :: RemoteFieldArgument -> RemoteFieldArgument -> Bool # (/=) :: RemoteFieldArgument -> RemoteFieldArgument -> Bool # | |
Show RemoteFieldArgument Source # | |
Defined in Hasura.RQL.IR.RemoteSchema showsPrec :: Int -> RemoteFieldArgument -> ShowS # show :: RemoteFieldArgument -> String # showList :: [RemoteFieldArgument] -> ShowS # |
data RemoteSchemaSelect r Source #
convertSelectionSet :: forall var. Eq var => SelectionSet Void var -> SelectionSet NoFragments var Source #
Converts a normalized selection set back into a selection set as defined in GraphQL spec, in order to send it to a remote server.
This function expects a SelectionSet
for which r
is Void
, which
guarantees that there is no longer any remote join field in the selection
set.
convertGraphQLField :: Eq var => GraphQLField Void var -> Field NoFragments var Source #
reduceAbstractTypeSelectionSet :: Eq var => DeduplicatedSelectionSet Void var -> (ObjectSelectionSet Void var, HashMap Name (ObjectSelectionSet Void var)) Source #
Builds the selection set for an abstract type.
Let's consider this query on starwars API:
The type Node
an interface is implemented by Film
, Species
, Planet
,
Person
, Starship
, Vehicle
query f { node(id: "ZmlsbXM6MQ==") { __typename id ... on Film { title } ... on Species { name } } }
When we parse this, it gets normalized into this query:
query f { node(id: "ZmlsbXM6MQ==") { ... on Film { typename: typename id title } ... on Species { typename: typename id name } ... on Planet { typename: typename id } ... on Person { typename: typename id } ... on Starship { typename: typename id } ... on Vehicle { typename: typename id } } }
__typename
and id
get pushed to each of the member types. From the above
normalized selection set, we want to costruct a query as close to the
original as possible. We do this as follows:
- find the longest common set of fields that each selection set starts with
(in the above case, they are
__typename
andid
) - from the above list of fields, find the first field that cannot be
defined on the abstract type. The fields that can be defined on the
abstract type are all the fields that occur before the first non abstract
type field (in the above case, both` __typename` and
id
can be defined on theNode
type) - Strip the base selection set fields from all the member selection sets and filter out the member type selection sets that are subsumed by the base selection set
The above query now translates to this:
query f { node(id: "ZmlsbXM6MQ==") { typename: typename id ... on Film { title } ... on Species { name } } }
Note that it is not always possible to get the same shape as the original query and there is more than one approach to this. For example, we could have picked the selection set (that can be defined on the abstract type) that is common across all the member selection sets and used that as the base selection.
_FieldRemote :: forall r var. Prism' (Field r var) (SchemaRemoteRelationshipSelect r) Source #
_FieldGraphQL :: forall r var var. Prism (Field r var) (Field r var) (GraphQLField r var) (GraphQLField r var) Source #
fSelectionSet :: forall r var r. Lens (GraphQLField r var) (GraphQLField r var) (SelectionSet r var) (SelectionSet r var) Source #
fName :: forall r var. Lens' (GraphQLField r var) Name Source #
fDirectives :: forall r var. Lens' (GraphQLField r var) [Directive var] Source #
fArguments :: forall r var. Lens' (GraphQLField r var) (HashMap Name (Value var)) Source #
fAlias :: forall r var. Lens' (GraphQLField r var) Name Source #
dssMemberSelectionSets :: forall r var r var. Lens (DeduplicatedSelectionSet r var) (DeduplicatedSelectionSet r var) (HashMap Name (ObjectSelectionSet r var)) (HashMap Name (ObjectSelectionSet r var)) Source #
dssCommonFields :: forall r var. Lens' (DeduplicatedSelectionSet r var) (HashSet Name) Source #