Add a reader instance to the resolvers

The Reader contains a Name/Value hashmap, which will contain resolver
arguments.
This commit is contained in:
Eugen Wissner 2019-11-23 09:49:12 +01:00
parent 625d7100ca
commit 587aab005e
4 changed files with 35 additions and 8 deletions

View File

@ -14,6 +14,8 @@ All notable changes to this project will be documented in this file.
- `Language.GraphQL.AST.Transform` is isn't exposed publically anymore. - `Language.GraphQL.AST.Transform` is isn't exposed publically anymore.
- `Language.GraphQL.Schema.resolve` accepts a selection `Seq` (`Data.Sequence`) - `Language.GraphQL.Schema.resolve` accepts a selection `Seq` (`Data.Sequence`)
instead of a list. Selections are stored as sequences internally as well. instead of a list. Selections are stored as sequences internally as well.
- Add a reader instance to the resolver's monad stack. The Reader contains
a Name/Value hashmap, which will contain resolver arguments.
### Added ### Added
- Nested fragment support. - Nested fragment support.
@ -29,6 +31,19 @@ All notable changes to this project will be documented in this file.
- `Language.GraphQL.AST.Parser.type_`: Try type parsers in a variable - `Language.GraphQL.AST.Parser.type_`: Try type parsers in a variable
definition in a different order to avoid using `but`. definition in a different order to avoid using `but`.
### Removed
- `Language.GraphQL.AST.Arguments`. Use `[Language.GraphQL.AST.Argument]`
instead.
- `Language.GraphQL.AST.Directives`. Use `[Language.GraphQL.AST.Directives]`
instead.
- `Language.GraphQL.AST.VariableDefinitions`. Use
`[Language.GraphQL.AST.VariableDefinition]` instead.
- `Language.GraphQL.AST.FragmentName`. Use `Language.GraphQL.AST.Name` instead.
- `Language.GraphQL.Execute.Schema` - It was a resolver list, not a schema.
- `Language.GraphQL.Schema`: `enum`, `enumA`, `wrappedEnum` and `wrappedEnumA`.
Use `scalar`, `scalarA`, `wrappedScalar` and `wrappedScalarA` instead.
## [0.5.1.0] - 2019-10-22 ## [0.5.1.0] - 2019-10-22
### Deprecated ### Deprecated
- `Language.GraphQL.AST.Arguments`. Use `[Language.GraphQL.AST.Argument]` - `Language.GraphQL.AST.Arguments`. Use `[Language.GraphQL.AST.Argument]`

View File

@ -23,10 +23,10 @@ import Data.Text.Lazy.Builder.Int (decimal)
import Data.Text.Lazy.Builder.RealFloat (realFloat) import Data.Text.Lazy.Builder.RealFloat (realFloat)
import qualified Language.GraphQL.AST as Full import qualified Language.GraphQL.AST as Full
-- | Instructs the encoder whether a GraphQL should be minified or pretty -- | Instructs the encoder whether the GraphQL document should be minified or
-- printed. -- pretty printed.
-- --
-- Use 'pretty' and 'minified' to construct the formatter. -- Use 'pretty' or 'minified' to construct the formatter.
data Formatter data Formatter
= Minified = Minified
| Pretty Word | Pretty Word

View File

@ -23,6 +23,7 @@ module Language.GraphQL.Schema
import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Except (runExceptT) import Control.Monad.Trans.Except (runExceptT)
import Control.Monad.Trans.Reader (runReaderT)
import Data.Foldable (find, fold) import Data.Foldable (find, fold)
import Data.Maybe (fromMaybe) import Data.Maybe (fromMaybe)
import qualified Data.Aeson as Aeson import qualified Data.Aeson as Aeson
@ -102,9 +103,10 @@ resolveFieldValue :: MonadIO m
-> Field -> Field
-> CollectErrsT m (HashMap Text Aeson.Value) -> CollectErrsT m (HashMap Text Aeson.Value)
resolveFieldValue f resolveRight fld@(Field _ _ args _) = do resolveFieldValue f resolveRight fld@(Field _ _ args _) = do
result <- lift $ runExceptT . runActionT $ f args result <- lift $ reader . runExceptT . runActionT $ f args
either resolveLeft (resolveRight fld) result either resolveLeft (resolveRight fld) result
where where
reader = flip runReaderT $ Context mempty
resolveLeft err = do resolveLeft err = do
_ <- addErrMsg err _ <- addErrMsg err
return $ HashMap.singleton (aliasOrName fld) Aeson.Null return $ HashMap.singleton (aliasOrName fld) Aeson.Null

View File

@ -1,6 +1,7 @@
-- | Monad transformer stack used by the @GraphQL@ resolvers. -- | Monad transformer stack used by the @GraphQL@ resolvers.
module Language.GraphQL.Trans module Language.GraphQL.Trans
( ActionT(..) ( ActionT(..)
, Context(Context)
) where ) where
import Control.Applicative (Alternative(..)) import Control.Applicative (Alternative(..))
@ -8,10 +9,19 @@ import Control.Monad (MonadPlus(..))
import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Trans.Class (MonadTrans(..)) import Control.Monad.Trans.Class (MonadTrans(..))
import Control.Monad.Trans.Except (ExceptT) import Control.Monad.Trans.Except (ExceptT)
import Control.Monad.Trans.Reader (ReaderT)
import Data.HashMap.Strict (HashMap)
import Data.Text (Text) import Data.Text (Text)
import Language.GraphQL.AST.Core (Name, Value)
-- | Monad transformer stack used by the resolvers to provide error handling. -- | Resolution context holds resolver arguments.
newtype ActionT m a = ActionT { runActionT :: ExceptT Text m a } newtype Context = Context (HashMap Name Value)
-- | Monad transformer stack used by the resolvers to provide error handling
-- and resolution context (resolver arguments).
newtype ActionT m a = ActionT
{ runActionT :: ExceptT Text (ReaderT Context m) a
}
instance Functor m => Functor (ActionT m) where instance Functor m => Functor (ActionT m) where
fmap f = ActionT . fmap f . runActionT fmap f = ActionT . fmap f . runActionT
@ -25,7 +35,7 @@ instance Monad m => Monad (ActionT m) where
(ActionT action) >>= f = ActionT $ action >>= runActionT . f (ActionT action) >>= f = ActionT $ action >>= runActionT . f
instance MonadTrans ActionT where instance MonadTrans ActionT where
lift = ActionT . lift lift = ActionT . lift . lift
instance MonadIO m => MonadIO (ActionT m) where instance MonadIO m => MonadIO (ActionT m) where
liftIO = lift . liftIO liftIO = lift . liftIO