mercurius-js / mercurius-gateway

Mercurius federation support plugin
MIT License
17 stars 11 forks source link

Union types gateway support #59

Open Davide-Gheri opened 1 year ago

Davide-Gheri commented 1 year ago

As per this code comment https://github.com/mercurius-js/mercurius-gateway/blob/main/lib/gateway/make-resolver.js#L652 it seems that it is not possible to define a Query that returns a Union type with one of the included object types defined in another service.

E.g.:

With these two service schemas

# Post schema
type Post @key(fields: "id") {
    id: ID!
    title: String!
    authorId: Int!
}

extend type Query {
    findPost(id: ID!): Post
}
# Recipe schema
type Recipe @key(fields: "id") {
  id: ID!
  name: String!
  postId: Int!
}

extend type Post @key(fields: "id") {
  id: ID! @external
  recipes: [Recipe!]!
}

union SearchUnion = Recipe | Post

extend type Query {
  findRecipe(id: ID!): Recipe
  search: [SearchUnion!]!
}

and a dummy search resolver like this:

search: () => ([
  { __typename: 'Post', id: 1 },
  { __typename: 'Recipe', id: 1, name: 'recipe1', postId: 1 },
]);

The query throws the error Cannot read properties of undefined (reading 'has') I found out the error is thrown here.

Strangely if I change the returned array order (returning a Recipe before a Post) the error changes to Cannot return null for non-nullable field Post.title. (it works if I only ask for Post.id since it doesn't have to resolve fields from another service)

mcollina commented 1 year ago

Thanks for reporting! Would you like to send a Pull Request to address this issue? Remember to add unit tests.