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

Unable to query fields of union type even if all types in union are object types #22

Closed
vslinko opened this issue Jul 5, 2015 · 6 comments

Comments

@vslinko
Copy link

vslinko commented Jul 5, 2015

const Good = new GraphQLObjectType({
  name: 'Good',
  fields: {
    title: {type: GraphQLString}
  }
})

const Product = new GraphQLUnionType({
  name: 'Product',
  types: [Good],
  resolveType(root) {
    return Good
  }
})
{ errors:
   [ { message: 'Cannot query field title on Product',
       locations: [ { line: 14, column: 13 } ] } ] }
@vslinko
Copy link
Author

vslinko commented Jul 5, 2015

Found the solution — GraphQLInterfaceType should be used to union object types.

@vslinko vslinko closed this as completed Jul 5, 2015
@leebyron
Copy link
Contributor

leebyron commented Jul 5, 2015

This is intentional, when querying against a Union you must narrow the type by using a fragment.

{
  product {
    ... on Good {
      title
    }
  }
}

This ensures that your query will be resilient to the evolution of the type schema over time. When this client has shipped, and you introduce a new type into your Product union, your client can safely ignore those additional typed items. If you were to query a field without first specifying the concrete Object type, then a new type could be added which happens to have a title field and now your existing client is overfetching and potentially rendering incorrectly.

If title is a critical part of what a Product is, such that you want to guarantee that you can always query title regardless of what concrete Object type is in use, then you should use an Interface instead of a Union.

@xpepermint
Copy link

Can you please write an example? I get cannot query field {name} error no matter what I do when I call on common fields. Should I always call with fragments?

{
  product {
    title // common fields (all types)
    ... on Good {
      // other fields
    }
  }
}

@xpepermint
Copy link

@vslinko Thanks to this I know what you mean now.

@jasonkuhrt
Copy link
Contributor

jasonkuhrt commented Oct 18, 2022

It would be great to be able to opt out of this intentional safety check. In some apps where e.g. the same developer or team works the full stack then the better tradeoff for them might be that they can select on common fields of the union type. Yes it will crash if the union is extended by the server, but the queries are flatter/easier to make. Assuming there is only one right answer here for all apps and teams is not ideal IMO.

@0Dmitry
Copy link

0Dmitry commented Aug 17, 2023

Looks like if all types in a union implement an interface, containing the common fields, you can then query those common fields by narrowing to that interface.

interface CommonFields {
  name: String
}

type TypeA implements CommonFields {
  name: String
  fieldA: String
}

type TypeB implements CommonFields {
  name: String
  fieldB: String
}

union TypeAll = TypeA | TypeB

Then you can query a field of type TypeAll like this

{
  field {
    ...on CommonFields {
      name
    }
}

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

No branches or pull requests

5 participants