Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphQL Interface not implemented error when returning a list of interface types #455

Closed
njlr opened this issue Dec 15, 2023 · 1 comment · Fixed by #458
Closed

GraphQL Interface not implemented error when returning a list of interface types #455

njlr opened this issue Dec 15, 2023 · 1 comment · Fixed by #458

Comments

@njlr
Copy link
Contributor

njlr commented Dec 15, 2023

This script demonstrates the problem:

#r "nuget: FSharp.Data.GraphQL.Server, 1.0.7"

type IPet =
  abstract member Name : string

type Dog =
  {
    Name : string
    Bark : int
  }
  interface IPet with
    member this.Name = this.Name

type Cat =
  {
    Name : string
    Agility : int
  }
  interface IPet with
    member this.Name = this.Name

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

#nowarn "40"

let rec petType =
  Define.Interface<IPet>(
    name = "Pet",
    fields =
      [
        Define.Field("name", String, fun _ x -> x.Name)
      ],
    resolveType =
      fun x ->
        match x with
        | :? Dog -> dogType :> ObjectDef
        | :? Cat -> catType :> ObjectDef
        | _ -> failwith $"Invalid IPet object %s{x.GetType().FullName}"
  )

and dogType =
  Define.Object<Dog>(
    name = "Dog",
    fields =
      [
        Define.Field("name", String, fun _ x -> x.Name)
        Define.Field("bark", Int, fun _ x -> x.Bark)
      ],
    interfaces = [ petType ]
  )

and catType =
  Define.Object<Cat>(
    name = "Cat",
    fields =
      [
        Define.Field("name", String, fun _ x -> x.Name)
        Define.Field("agility", Int, fun _ x -> x.Agility)
      ],
    interfaces = [ petType ]
  )

let queryType =
  Define.Object<unit>(
    name = "Query",
    fields =
      [
        Define.Field(
          "pets",
          ListOf petType,
          fun _ () ->
            [
              { Name = "Fido"; Bark = 10 } :> IPet
              { Name = "Felix"; Agility = 8 } :> IPet
            ]
        )
      ]
  )

let config : SchemaConfig =
  {
    SchemaConfig.Default
      with
        Types =
          [
            dogType
            catType
          ]
  }

let schema = Schema(queryType, config = config)
let executor = Executor(schema)

let query =
  """
  {
    pets {
      ... on Dog {
        name
        bark
      }
    }
  }
  """

let result =
  executor.AsyncExecute(query)
  |> Async.RunSynchronously

printfn "%A" result
{ Content =
   Direct
     (seq
        [[documentId, -2037844746]; [data, ];
         [errors, [{ message: "GraphQL Interface 'Pet' is not implemented by the type 'Cat'",
		path: ["pets", 1, ] }]]],
      [("GraphQL Interface 'Pet' is not implemented by the type 'Cat'",
        ["pets"; 1])])
  Metadata = map [] }

Curiously, these queries work as expected:

{
  pets {
    name
    ... on Dog {
      bark
    }
  }
}
{
  pets {
    ... on Cat {
      name
      agility
    }
    ... on Dog {
      name
      bark
    }
  }
}
@xperiandri
Copy link
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants