morpheus-graphql icon indicating copy to clipboard operation
morpheus-graphql copied to clipboard

Morpheus doesn't support singleton list input coercion

Open nicuveo opened this issue 3 years ago • 1 comments

Description

As per section 3.11 of the GraphQL spec, lists are subject to Input Coercion. One such possible coercion is the promotion of singleton lists:

If the value passed as an input to a list type is not a list and not the null value, then the result of input coercion is a list of size one, where the single item value is the result of input coercion for the list’s item type on the provided value.

AFAICT, Morpheus doesn't support this, and incorrectly rejects such incoming requests.

Steps to reproduce

Define a server with the following schema:

type Query {
  foo(bar: [Int!]): Int!
}

send the following request:

query {
  foo(bar: 3)
}

The query fails with:

- message: 'Argument "bar" got invalid value. Expected type "[Int!]"
    found 3.'

Notes

My test case was slightly more complicated, and I haven't made a small repro case I can attach to this issue. I can do that if that's helpful?

nicuveo avatar Feb 22 '22 22:02 nicuveo

Here's a quick repro case!

import Data.Morpheus.Document
import Data.Morpheus.Types
import Data.Morpheus

[gqlDocument|
type Query {
  foo(bar: [Int]!): Int!
}
|]

queryRoot :: Query (Resolver QUERY () IO)
queryRoot = Query {foo}
  where
    foo (Arg bar) = pure $ length bar

main = do
  let
    service :: GQLRequest -> IO GQLResponse
    service = interpreter $ RootResolver queryRoot Undefined Undefined
    send q = service $ GQLRequest
      { operationName = Nothing
      , variables = Nothing
      , query = q
      }
  print =<< send "query { foo(bar: [3]) }"
  print =<< send "query { foo(bar: 3) }"

This prints:

Data (Object (OrdMap {mapEntries = fromList [("foo",Indexed {index = 0, indexedKey = "foo", indexedValue = ObjectEntry {entryName = "foo", entryValue = Scalar (Int 1)}})]}))
Errors [GQLError {message = "Argument \"bar\" got invalid value. Expected type \"[Int]!\" found 3.", locations = Just [Position {line = 1, column = 13}], path = Nothing, errorType = Nothing, extensions = Nothing}]

nicuveo avatar Feb 23 '22 13:02 nicuveo