Skip to main content

Struct type

At a glance​

  • Identifier: wg#1071
  • Stage: RFC0: Strawman
  • Champion: @benjie
  • PR: -
  • Related:
    • #733 (Tagged type)
    • #825 (OneOf Input Objects)
    • Struct (Polymorphic-capable composite symmetric input/output type (`struct`))


Whilst talking with @IvanGoncharov about metadata and the need for a structured type that's valid on both input and output, Ivan suggested that we might have a scalar "model" an input object, such that the scalar (which is valid on input and output) could be given a structure. Hot on the heels of @oneOf I wondered if we could just give input more powers and explored this idea further, and the struct RFC is the result of that exploration. It turns out that doing this would solve a number of the open issues people have discussed in the GraphQL spec repository issues, and may also be a more suitable solution to input polymorphism.

Think of struct as "a scalar with structure". A struct represents some fixed data, like { "type": "Feature", "geometry": { "type": "Point", "coordinates": [125.6, 10.1] }, "properties": { "name": "Dinagat Islands" } }, that could be sent from the client to the server, or from the server to the client, as an "atom" - without any further resolution.

No resolvers. No field arguments. No infinite recursion. Just pure data.

The struct type could be implemented as:

  1. an enhancement over a scalar, giving the scalar fields and thus structure
  2. an enhancement of input, allowing it to be used on output
  3. a new "struct" type.

Given Lee pushed towards (3) for the "tagged type" when exploring oneOf, I explored that first. The problem that came up was the same one that came up for using scalars (1): it suddenly becomes unclear when an input object should be used, versus when a struct should be used. So it was clear that option (2) was the most promising.

The biggest issue I see with option (2) is literally the name: "input". Using a type named "input" for output would certainly be unexpected. But since that's potentially just a "historical accident" let​'s ignore that for now πŸ˜‰

I've used the keyword struct in the RFC, but it does not need a new keyword (reusing input would be fine), I just wanted to make the distinction clear and to not have to rewrite everything if we chose an option other than (2) in future.

In the RFC I've laid out a number of justifications why the struct type is useful, what it might look like, and have even explored what (optional) selection sets over the type might look like.

If you have feedback on this RFC, this is the place to raise it before our next working group on August.

Thanks to @IvanGoncharov, @michaelstaib and @andimarek for helping shape this RFC with their feedback.