{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE NoImplicitPrelude #-} module Data.Morpheus.Types.IO ( GQLRequest (..), GQLResponse (..), renderResponse, ) where import Data.Aeson ( FromJSON (..), ToJSON (..), object, pairs, (.=), ) import qualified Data.Aeson as Aeson ( Value (..), ) import Data.Morpheus.Ext.Result ( Result (..), ) import Data.Morpheus.Internal.Utils ( toAssoc, ) import Data.Morpheus.Types.Internal.AST ( FieldName, GQLError (..), ValidValue, ) import Relude hiding ( decodeUtf8, encodeUtf8, ) renderResponse :: Result GQLError ValidValue -> GQLResponse renderResponse (Failure errors) = Errors $ sort $ toList errors renderResponse Success {result} = Data result -- | GraphQL HTTP Request Body data GQLRequest = GQLRequest { operationName :: Maybe FieldName, query :: Text, variables :: Maybe Aeson.Value } deriving (Show, Generic, FromJSON, ToJSON) -- | GraphQL Response data GQLResponse = Data ValidValue | Errors [GQLError] deriving (Show, Generic) instance FromJSON GQLResponse where parseJSON (Aeson.Object hm) = case toAssoc 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 toJSON (Data gqlData) = object ["data" .= toJSON gqlData] toJSON (Errors errors) = object ["errors" .= toJSON errors] ---------------------------------------------------------- toEncoding (Data _data) = pairs $ "data" .= _data toEncoding (Errors _errors) = pairs $ "errors" .= _errors