summaryrefslogtreecommitdiff
path: root/src/Language/GraphQL.hs
blob: 949fd068fa45ab87205789611189c8f7eb9b50c4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
{-# LANGUAGE RecordWildCards #-}

-- | This module provides the functions to parse and execute @GraphQL@ queries.
module Language.GraphQL
    ( graphql
    ) where

import Control.Monad.Catch (MonadCatch)
import Data.HashMap.Strict (HashMap)
import qualified Data.Sequence as Seq
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Language.GraphQL.AST as Full
import Language.GraphQL.Error
import Language.GraphQL.Execute
import qualified Language.GraphQL.Validate as Validate
import Language.GraphQL.Type.Schema (Schema)
import Prelude hiding (null)
import Text.Megaparsec (parse)

-- | If the text parses correctly as a @GraphQL@ query the query is
-- executed using the given 'Schema'.
--
-- An operation name can be given if the document contains multiple operations.
graphql :: (MonadCatch m, VariableValue a, Serialize b)
    => Schema m -- ^ Resolvers.
    -> Maybe Text -- ^ Operation name.
    -> HashMap Full.Name a -- ^ Variable substitution function.
    -> Text -- ^ Text representing a @GraphQL@ request document.
    -> m (Either (ResponseEventStream m b) (Response b)) -- ^ Response.
graphql schema operationName variableValues document' =
    case parse Full.document "" document' of
        Left errorBundle -> pure  <$> parseError errorBundle
        Right parsed ->
            case validate parsed of
                Seq.Empty -> execute schema operationName variableValues parsed
                errors -> pure $ pure
                    $ Response null
                    $ fromValidationError <$> errors
  where
    validate = Validate.document schema Validate.specifiedRules
    fromValidationError Validate.Error{..} = Error
        { message = Text.pack message
        , locations = locations
        , path = []
        }