Skip to main content

OneOf Objects

At a glance​

Timeline​


This is a follow-up to #825 that proposes adding the @oneOf directive to object types (output objects).

This is a draft right now as I've not yet had time to think through it well enough, but it raises a few questions:

  1. The proposed resolution algorithm is a slight divergence from the status quo, omitting fields from the response rather than setting them null. This makes it align with #825, but is it desired? Should we change #825 to only require​ one non-null field rather than just one field?
  2. Should we allow aliases? The current proposed resolution algorithm ensures that every identical field requested on a @oneOf selection set will get the same value, but it does so in a somewhat awkward way. Forbidding aliases could remove the need for this.
  3. What happens if a @oneOf is queried as part of a union? The proposed resolution algorithm allows for this by leaving it up to the implementation, I think this is probably best unless anyone has a better idea?

TODO:

  • When validating the schema, forbid @oneOf on operation types.
  • Tidy up the language around maps/accessing keys.

Note this PR is based off of #825, so this is probably the diff you want:

https://github.com/benjie/graphql-spec/compare/oneof-v2..oneof-output

Other notes:

  • Seems like @stream, @defer, @skip and @include are all compatible with oneOf.
  • Aliases don't need to cause a problem; they'll make the client's life harder, but if it's the client requesting it then that's their problem 😆
  • The fields on a @oneOf don't have their own traditional resolvers, instead the parent value must dictate which key/value was returned. This prevents confusion where the same field being requested multiple times ({ a1: a, a2: a, a3: a }) could result in different values - we explicitly prevent this from happening.