Skip unknown fields

This commit is contained in:
Eugen Wissner 2020-06-10 11:42:00 +02:00
parent fdb1268213
commit c37b9c88b1
4 changed files with 51 additions and 10 deletions

View File

@ -13,10 +13,11 @@ and this project adheres to
constants cannot be variables. `AST.Document.ConstValue` was added,
`AST.Document.ObjectField` was modified.
- AST transformation should never fail.
* Missing variable are assumed to be null.
* Arguments and fields with a missing variable as value should be left out.
* Invalid (recusrive or non-existing) fragments should be skipped.
- Argument value coercion.
- Variable value coercion.
- The executor should skip the fields missing in the object type and not fail.
### Changed
- `Schema.Resolver` was moved to `Type.Out`, it is a field and resolver function

View File

@ -17,7 +17,6 @@ import qualified Data.Map.Strict as Map
import Data.Maybe (fromMaybe)
import Data.Sequence (Seq(..))
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Sequence as Seq
import Language.GraphQL.AST (Name)
import Language.GraphQL.AST.Core
@ -100,10 +99,10 @@ instanceOf objectType (AbstractUnionType unionType) =
executeField :: Monad m
=> Definition.Value
-> Out.Resolver m
-> Field m
-> Out.Resolver m
-> CollectErrsT m Aeson.Value
executeField prev (Out.Resolver fieldDefinition resolver) field = do
executeField prev field (Out.Resolver fieldDefinition resolver) = do
let Out.Field _ fieldType argumentDefinitions = fieldDefinition
let Field _ _ arguments' _ = field
case coerceArgumentValues argumentDefinitions arguments' of
@ -160,13 +159,12 @@ executeSelectionSet result objectType@(Out.ObjectType _ _ _ resolvers) selection
pure $ Aeson.toJSON resolvedValues
where
forEach _responseKey (field :<| _) =
tryResolvers field >>= lift . pure . pure
let Field _ name _ _ = field
in traverse (tryResolver field) $ lookupResolver name
forEach _ _ = pure Nothing
lookupResolver = flip HashMap.lookup resolvers
tryResolvers fld@(Field _ name _ _)
| Just typeField <- lookupResolver name =
executeField result typeField fld
| otherwise = errmsg $ Text.unwords ["field", name, "not resolved."]
tryResolver typeField field =
executeField result typeField field >>= lift . pure
coerceArgumentValues
:: HashMap Name In.Argument

View File

@ -1,4 +1,4 @@
resolver: lts-15.16
resolver: lts-16.0
packages:
- .

View File

@ -0,0 +1,42 @@
{-# LANGUAGE OverloadedStrings #-}
module Language.GraphQL.ExecuteSpec
( spec
) where
import Data.Aeson ((.=))
import qualified Data.Aeson as Aeson
import Data.Functor.Identity (Identity(..))
import Data.HashMap.Strict (HashMap)
import qualified Data.HashMap.Strict as HashMap
import Language.GraphQL.AST (Name)
import Language.GraphQL.AST.Parser (document)
import Language.GraphQL.Error
import Language.GraphQL.Execute
import Language.GraphQL.Type
import Language.GraphQL.Type.Out as Out
import Test.Hspec (Spec, describe, it, shouldBe)
import Text.Megaparsec (parse)
schema :: Schema Identity
schema = Schema {query = queryType, mutation = Nothing}
queryType :: Out.ObjectType Identity
queryType = Out.ObjectType "Query" Nothing []
$ HashMap.singleton "count"
$ Out.Resolver countField
$ pure
$ Int 8
where
countField = Out.Field Nothing (Out.NonNullScalarType int) HashMap.empty
spec :: Spec
spec =
describe "execute" $
it "skips unknown fields" $
let expected = Aeson.object
["data" .= Aeson.object ["count" .= (8 :: Int)]]
execute' = execute schema (mempty :: HashMap Name Aeson.Value)
actual = runIdentity
$ either parseError execute'
$ parse document "" "{ count number }"
in actual `shouldBe` expected