Repository navigation
Allow empty selection sets - #1227
Conversation
✅ Deploy Preview for graphql-spec-draft ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
8c13477 to
220e8d4
Compare
|
I believe this is ready to merge, pending @yaacovCR's feedback on the GraphQL.js PR: |
|
If we're going to merge this, I think we can takeoff the experimental label on the associated PR? |
Excellent observation @yaacovCR. We can even probably drop the parameter altogether? |
|
I made another version of the PR if we decide to expedite this: My preference goes to "without experimental flag". Less complexity is better. |
|
I personally would keep the flag until next semver major, even if you default to enabling the feature. Reason: their security systems might not be set up to handle queries like this; consider: {
user {
a: friends {}
b: friends {}
c: friends {}
}
}if they're using complexity cost that multiples expected list length by selection set cost, and selection set cost is zero because there's no fields (previously not possible), it might have an impact on their security. (The IBM cost spec does not suffer from this AFAIK, but there are lots of models of query cost in the wild.) There may be other such concerns that we're not yet aware of, so giving people a way to opt out until v18 does not seem unwise. |
Works for me. All in all:
I have updated the PR in that direction. Let me know if something else is preferred. |
|
We'll merge this during the secondary WG on Thursday 17th unless anyone has reservations (express them now!) |
The September 2026 spec changes the grammar to `SelectionSet : { Selection* }`
(graphql/graphql-spec#1227), so `query {}` and `{ human {} }` are valid.
Field sets share this grammar and also accept an empty selection; rejecting
empty `@key`/`@requires` field sets is left to composition.
Compiler diagnostic fixture 0011 relied on `{}` being a syntax error, so it
now uses a missing argument value instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(parser): accept empty selection sets
The September 2026 spec changes the grammar to `SelectionSet : { Selection* }`
(graphql/graphql-spec#1227), so `query {}` and `{ human {} }` are valid.
Field sets share this grammar and also accept an empty selection; rejecting
empty `@key`/`@requires` field sets is left to composition.
Compiler diagnostic fixture 0011 relied on `{}` being a syntax error, so it
now uses a missing argument value instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(parser): link changelog entry to pull/1115
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
) * feat(parser): accept empty selection sets The September 2026 spec changes the grammar to `SelectionSet : { Selection* }` (graphql/graphql-spec#1227), so `query {}` and `{ human {} }` are valid. Field sets share this grammar and also accept an empty selection; rejecting empty `@key`/`@requires` field sets is left to composition. Compiler diagnostic fixture 0011 relied on `{}` being a syntax error, so it now uses a missing argument value instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(parser): link changelog entry to pull/1115 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * feat(compiler)!: distinguish empty subselections from leaf fields The September 2026 spec allows `{ human {} }`. Field subselections were a `Vec`, so `human {}` and `human` were indistinguishable and the printer dropped the braces, turning a valid document into an invalid one on round trip. `ast::Field.selection_set` is now `Option<Vec<Selection>>` and `executable::Field.selection_set` is now `Option<SelectionSet>`. An `Option` rather than a presence flag means downstream code that builds leaf fields with an empty selection set fails to compile instead of silently printing `field {}`. Leaf validation now checks presence instead of emptiness, so `name {}` on a scalar is rejected and `human {}` on an object is accepted. Executing an empty subselection yields `{}`. apollo-smith is updated only as far as needed to compile against the new types. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * docs(compiler): link changelog entry to pull/1116 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
See graphql/graphql-spec#1227 New (and already deprecated!) parser/validation option `allowEmptySelectionSets` defaults to true, allowing empty selection sets. This option can be used to preserve the old behavior disallowing empty selection sets. --------- Co-authored-by: Benjie <benjie@jemjie.com>
Since 2015 we've required selection sets to contain at least one field; however it's always been possible to have an empty object returned:
Here, if
ureturns typeBthe result will be{"data":{"u":{}}}- i.e. an empty object.GraphQL clients are getting smarter and smarter, and it's common to have client-side extensions such as Apollo's @client, Relay Resolvers or
@mock'd fields. In all of these cases, any selections of these fields need to be removed before the document is sent to the server. But what happens when all the fields in the selection set are to be removed?There are many options (add
__typename, removelaunch, throw error, ...), but the safest solution is to allow the selection set to be empty. Hence, this PR.