FSharp.Data.GraphQL icon indicating copy to clipboard operation
FSharp.Data.GraphQL copied to clipboard

"Object must implement IConvertible" when using built-in ID

Open mjarosie opened this issue 5 years ago • 3 comments

Description

When using built-in ID GraphQL type to represent the Guid .NET type I'm getting Object must implement IConvertible error back from the executor.

Repro steps

open FSharp.Data.GraphQL
open FSharp.Data.GraphQL.Types

type Person =
    { Id: System.Guid
      Name: string }

let people: List<Person> = [ 
    { Id = System.Guid.Parse("d6c684d9-aaaa-4e88-bbb2-0bb584f1661d"); Name = "Person A" }
    { Id = System.Guid.Parse("d6c684d9-bbbb-4e88-bbb2-0bb584f1661d"); Name = "Person B" } ]

let ProjectType: ObjectDef<Person> = Define.Object(
    name = "Person",
    fields = [
        Define.AutoField("id", ID)
        Define.AutoField("name", String)
    ])

let QueryRoot = Define.Object("Query", [
    Define.Field("people", ListOf ProjectType, fun ctx () -> 
        printfn "Querying for people"
        people
    )
])

let schema = Schema(query = QueryRoot)

let executor = Executor(schema = schema)

let query = "{people{id}}"
let result = executor.AsyncExecute(query) |> Async.RunSynchronously
printfn "%A" result

Expected behavior

I'm getting a list of people IDs back.

Actual behavior

I'm receiving the following error:

System.InvalidCastException: Object must implement IConvertible.\r\n   at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)\r\n   at System.Convert.ChangeType(Object value, Type conversionType)\r\n   at FSharp.Data.GraphQL.Types.SchemaDefinitions.coerceIDValue[t](Object x)\r\n   at [email protected](Object x)\r\n   at FSharp.Data.GraphQL.Types.ScalarDefinition`1.FSharp-Data-GraphQL-Types-ScalarDef-CoerceValue(Object value)\r\n   at FSharp.Data.GraphQL.Execution.direct(OutputDef returnDef, ResolveFieldContext ctx, FSharpList`1 path, Object parent, Object value)\r\n   at FSharp.Data.GraphQL.Execution.executeObjectFields(FSharpList`1 fields, String objName, ObjectDef objDef, ResolveFieldContext ctx, FSharpList`1 path, Object value)\r\n   at Microsoft.FSharp.Collections.ArrayModule.MapIndexed[T,TResult](FSharpFunc`2 mapping, T[] array) in F:\\workspace\\_work\\1\\s\\src\\fsharp\\FSharp.Core\\array.fs:line 349\r\n   at FSharp.Data.GraphQL.Execution.direct$cont@329-1(ResolveFieldContext ctx, FSharpList`1 path, Object value, String name, OutputDef innerDef, Unit unitVar)\r\n   at FSharp.Data.GraphQL.Execution.direct$cont@312(OutputDef returnDef, ResolveFieldContext ctx, FSharpList`1 path, Object parent, Object value, String name, Unit unitVar)\r\n   at FSharp.Data.GraphQL.Execution.executeRootOperation@563(ExecutionContext ctx, ObjectDef objdef, Object rootValue, String tupledArg0, ExecutionInfo tupledArg1)\r\n   at FSharp.Data.GraphQL.Execution.executeQueryOrMutation(Tuple`2[] resultSet, ExecutionContext ctx, ObjectDef objdef, Object rootValue)\r\n   at <StartupCode$FSharp-Data-GraphQL-Server>[email protected](Unit unitVar)\r\n   at Microsoft.FSharp.Control.AsyncPrimitives.CallThenInvoke[T,TResult](AsyncActivation`1 ctxt, TResult result1, FSharpFunc`2 part2) in F:\\workspace\\_work\\1\\s\\src\\fsharp\\FSharp.Core\\async.fs:line 398\r\n   at Microsoft.FSharp.Control.Trampoline.Execute(FSharpFunc`2 firstAction) in F:\\workspace\\_work\\1\\s\\src\\fsharp\\FSharp.Core\\async.fs:line 109

Known workarounds

You can change the Type definition of the Guid field to be just a String, but semantically that's not correct (I'm still getting my head around GraphQL, but as far as I know that's the whole purpose of using ID type - it is not intended to be human‐readable):

let ProjectType: ObjectDef<Person> = Define.Object(
    name = "Person",
    fields = [
        Define.AutoField("id", String)
        Define.AutoField("name", String)
    ])

mjarosie avatar Oct 21 '20 15:10 mjarosie

As it turns out it's just the AutoField which doesn't work for ID:

Define.Field("id", ID, (fun _ person -> person.Id )) // Works
Define.AutoField("id", ID) // Doesn't work as shown above

mjarosie avatar Oct 21 '20 15:10 mjarosie

I think FSharp.Data.GraphQL.Types.Guid should be used here

njlr avatar Sep 17 '21 17:09 njlr

@mjarosie try with the latest package from GitHub feed. If not fixed I'll take care

xperiandri avatar Nov 05 '23 23:11 xperiandri