{-# LANGUAGE OverloadedStrings #-}
module Language.GraphQL.Execute
( execute
, module Language.GraphQL.Execute.Coerce
) where
import Control.Monad.Catch (MonadCatch)
import Data.HashMap.Strict (HashMap)
import Data.Sequence (Seq(..))
import Data.Text (Text)
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 qualified Language.GraphQL.Execute.Subscribe as Subscribe
import Language.GraphQL.Error
import qualified Language.GraphQL.Type.Definition as Definition
import qualified Language.GraphQL.Type.Out as Out
import Language.GraphQL.Type.Schema
execute :: (MonadCatch m, VariableValue a, Serialize b)
=> Schema m
-> Maybe Text
-> HashMap Name a
-> Document
-> m (Either (ResponseEventStream m b) (Response b))
execute schema operationName subs document =
case Transform.document schema operationName subs document of
Left queryError -> pure
$ Right
$ singleError
$ Transform.queryError queryError
Right transformed -> executeRequest transformed
executeRequest :: (MonadCatch m, Serialize a)
=> Transform.Document m
-> m (Either (ResponseEventStream m a) (Response a))
executeRequest (Transform.Document types' rootObjectType operation)
| (Transform.Query _ fields) <- operation =
Right <$> executeOperation types' rootObjectType fields
| (Transform.Mutation _ fields) <- operation =
Right <$> executeOperation types' rootObjectType fields
| (Transform.Subscription _ fields) <- operation
= either (Right . singleError) Left
<$> Subscribe.subscribe types' rootObjectType fields
executeOperation :: (MonadCatch m, Serialize a)
=> HashMap Name (Type m)
-> Out.ObjectType m
-> Seq (Transform.Selection m)
-> m (Response a)
executeOperation types' objectType fields =
runCollectErrs types' $ executeSelectionSet Definition.Null objectType fields