{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedStrings #-}
module Data.Morpheus.Types.IO
( GQLRequest(..)
, GQLResponse(..)
, JSONResponse(..)
, renderResponse
)
where
import Data.Aeson ( FromJSON(..)
, ToJSON(..)
, pairs
, withObject
, (.:?)
, (.=)
)
import qualified Data.Aeson as Aeson
( Value(..) )
import qualified Data.HashMap.Lazy as LH
( toList )
import GHC.Generics ( Generic )
import Data.Morpheus.Types.Internal.AST.Base
( Key )
import Data.Morpheus.Types.Internal.Resolving.Core
( GQLError(..)
, Result(..)
)
import Data.Morpheus.Types.Internal.AST.Value
( ValidValue )
renderResponse :: Result e GQLError con ValidValue -> GQLResponse
renderResponse (Failure errors) = Errors errors
renderResponse Success { result } = Data result
instance FromJSON a => FromJSON (JSONResponse a) where
parseJSON = withObject "JSONResponse" objectParser
where objectParser o = JSONResponse <$> o .:? "data" <*> o .:? "errors"
data JSONResponse a = JSONResponse
{ responseData :: Maybe a
, responseErrors :: Maybe [GQLError]
} deriving (Generic, Show, ToJSON)
data GQLRequest = GQLRequest
{ query :: Key
, operationName :: Maybe Key
, variables :: Maybe Aeson.Value
} deriving (Show, Generic, FromJSON, ToJSON)
data GQLResponse
= Data ValidValue
| Errors [GQLError]
deriving (Show, Generic)
instance FromJSON GQLResponse where
parseJSON (Aeson.Object hm) = case LH.toList hm of
[("data" , value)] -> Data <$> parseJSON value
[("errors", value)] -> Errors <$> parseJSON value
_ -> fail "Invalid GraphQL Response"
parseJSON _ = fail "Invalid GraphQL Response"
instance ToJSON GQLResponse where
toEncoding (Data _data ) = pairs $ "data" .= _data
toEncoding (Errors _errors) = pairs $ "errors" .= _errors