ghostdogpr / caliban

Functional GraphQL library for Scala

Home Page:https://ghostdogpr.github.io/caliban/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Field types are `String` for interface fields selected on a union

guymers opened this issue · comments

Given the follow schema (extended from the one in FieldSpec):

union Union = A | B

interface Interface { id: String!  inner: Inner! }

type A implements Interface { id: String!  inner: Inner! }
type B implements Interface { id: String!  inner: Inner!  count: Int! }
type C implements Interface { id: String!  inner: Inner! }

type Inner { num: Int! }

type Queries {
  union: Union!
  interface: Interface!
}

Fetching on the interface returns the expected field types:

{
  interface {
    ... on Interface {
      id
      inner { num }
    }
    ... on B {
      ... on Interface { id }
      inner { num }
      count
    }
  }
}
{
  interface (Interface!) {
    id (String!)
    inner (Inner!) {
      num (Int!)
    }
    id (String!)
    inner (Inner!) {
      num (Int!)
    }
    count (Int!)
  }  
}

Fetching on the union returns the following field types:

{
  union {
    ... on Interface {
      id
      inner { num }
    }
    ... on B {
      ... on Interface { id }
      inner { num }
      count
    }
  }
}
{
  union (Union!) {
    id (String)
    inner (String) {
      num (String)
    }
    id (String!)
    inner (Inner!) {
      num (Int!)
    }
    count (Int!)
  }  
}

Note that everything being fetched on Interface at the union level says it is a String.

Here is a basic test case https://gist.github.com/guymers/df3eb754ca556cd59b8c2f87740ec62b

I think adding

.orElse(typeCondition.map(_.name).flatMap(rootType.types.get))

right after

.flatMap(_.find(_.name.exists(typeCondition.map(_.name).contains)))

in Field.scala would fix it.

Basically, we search among the possible types of the union first, but if we don't find it we should look at other types to find a potential interface.

Can you confirm it works for you?
I can't apply your diff because it doesn't match with the latest master so if it's working you can submit the fix with your tests.