aboutsummaryrefslogtreecommitdiff
path: root/src/Language/GraphQL/Execute.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Language/GraphQL/Execute.hs')
-rw-r--r--src/Language/GraphQL/Execute.hs87
1 files changed, 36 insertions, 51 deletions
diff --git a/src/Language/GraphQL/Execute.hs b/src/Language/GraphQL/Execute.hs
index 204d08c..45bace0 100644
--- a/src/Language/GraphQL/Execute.hs
+++ b/src/Language/GraphQL/Execute.hs
@@ -1,5 +1,3 @@
-{-# LANGUAGE OverloadedStrings #-}
-
-- | This module provides functions to execute a @GraphQL@ request.
module Language.GraphQL.Execute
( execute
@@ -7,33 +5,30 @@ module Language.GraphQL.Execute
) where
import qualified Data.Aeson as Aeson
-import Data.List.NonEmpty (NonEmpty(..))
-import qualified Data.List.NonEmpty as NonEmpty
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
+import Data.Sequence (Seq(..))
import Data.Text (Text)
-import qualified Data.Text as Text
-import Language.GraphQL.AST.Document
-import qualified Language.GraphQL.AST.Core as AST.Core
+import Language.GraphQL.AST.Document (Document, Name)
+import Language.GraphQL.Execute.Coerce
+import Language.GraphQL.Execute.Execution
import qualified Language.GraphQL.Execute.Transform as Transform
import Language.GraphQL.Error
-import qualified Language.GraphQL.Schema as Schema
+import qualified Language.GraphQL.Type.Definition as Definition
+import qualified Language.GraphQL.Type.Out as Out
+import Language.GraphQL.Type.Schema
-- | The substitution is applied to the document, and the resolvers are applied
-- to the resulting fields.
--
-- Returns the result of the query against the schema wrapped in a /data/
-- field, or errors wrapped in an /errors/ field.
-execute :: Monad m
- => HashMap Text (NonEmpty (Schema.Resolver m)) -- ^ Resolvers.
- -> Schema.Subs -- ^ Variable substitution function.
+execute :: (Monad m, VariableValue a)
+ => Schema m -- ^ Resolvers.
+ -> HashMap.HashMap Name a -- ^ Variable substitution function.
-> Document -- @GraphQL@ document.
-> m Aeson.Value
-execute schema subs doc =
- maybe transformError (document schema Nothing)
- $ Transform.document subs doc
- where
- transformError = return $ singleError "Schema transformation error."
+execute schema = executeRequest schema Nothing
-- | The substitution is applied to the document, and the resolvers are applied
-- to the resulting fields. The operation name can be used if the document
@@ -41,46 +36,36 @@ execute schema subs doc =
--
-- Returns the result of the query against the schema wrapped in a /data/
-- field, or errors wrapped in an /errors/ field.
-executeWithName :: Monad m
- => HashMap Text (NonEmpty (Schema.Resolver m)) -- ^ Resolvers
+executeWithName :: (Monad m, VariableValue a)
+ => Schema m -- ^ Resolvers
-> Text -- ^ Operation name.
- -> Schema.Subs -- ^ Variable substitution function.
+ -> HashMap.HashMap Name a -- ^ Variable substitution function.
-> Document -- ^ @GraphQL@ Document.
-> m Aeson.Value
-executeWithName schema name subs doc =
- maybe transformError (document schema $ Just name)
- $ Transform.document subs doc
- where
- transformError = return $ singleError "Schema transformation error."
+executeWithName schema operationName =
+ executeRequest schema (Just operationName)
-document :: Monad m
- => HashMap Text (NonEmpty (Schema.Resolver m))
+executeRequest :: (Monad m, VariableValue a)
+ => Schema m
-> Maybe Text
- -> AST.Core.Document
+ -> HashMap.HashMap Name a
+ -> Document
-> m Aeson.Value
-document schema Nothing (op :| []) = operation schema op
-document schema (Just name) operations = case NonEmpty.dropWhile matchingName operations of
- [] -> return $ singleError
- $ Text.unwords ["Operation", name, "couldn't be found in the document."]
- (op:_) -> operation schema op
- where
- matchingName (AST.Core.Query (Just name') _) = name == name'
- matchingName (AST.Core.Mutation (Just name') _) = name == name'
- matchingName _ = False
-document _ _ _ = return $ singleError "Missing operation name."
+executeRequest schema operationName subs document =
+ case Transform.document schema operationName subs document of
+ Left queryError -> pure $ singleError $ Transform.queryError queryError
+ Right (Transform.Document types' rootObjectType operation)
+ | (Transform.Query _ fields) <- operation ->
+ executeOperation types' rootObjectType fields
+ | (Transform.Mutation _ fields) <- operation ->
+ executeOperation types' rootObjectType fields
-operation :: Monad m
- => HashMap Text (NonEmpty (Schema.Resolver m))
- -> AST.Core.Operation
+-- This is actually executeMutation, but we don't distinguish between queries
+-- and mutations yet.
+executeOperation :: Monad m
+ => HashMap Name (Type m)
+ -> Out.ObjectType m
+ -> Seq (Transform.Selection m)
-> m Aeson.Value
-operation schema = schemaOperation
- where
- runResolver fields = runCollectErrs
- . flip Schema.resolve fields
- . Schema.resolversToMap
- resolve fields queryType = maybe lookupError (runResolver fields)
- $ HashMap.lookup queryType schema
- lookupError = pure
- $ singleError "Root operation type couldn't be found in the schema."
- schemaOperation (AST.Core.Query _ fields) = resolve fields "Query"
- schemaOperation (AST.Core.Mutation _ fields) = resolve fields "Mutation"
+executeOperation types' objectType fields =
+ runCollectErrs types' $ executeSelectionSet Definition.Null objectType fields