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

[RFC] allow empty selections #674

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

kassens
Copy link

@kassens kassens commented Jan 21, 2020

Sometimes, product code might only be interested in the existence of an object. Currently, this forces a workaround of either querying __typename or adding a bool field like has_thing.

It seems natural and not too confusing to allow empty selections:

query {
  event {
    location {}
  }
}

The response should either return null or an empty object for location.

(The spec changes are incomplete.)

Sometimes, product code might only be interested in the existence of an
object. Currently, this forces a workaround of either querying
`__typename` or adding a bool field like `has_thing`.

It seems natural and not too confusing to allow empty selections:

```
query {
  event {
    location {}
  }
}
```

The response should either return `null` or an empty object for
`location`.
@kassens kassens changed the title [RFC] allow empty selections [RFC][strawman] allow empty selections Jan 21, 2020
@IvanGoncharov IvanGoncharov added the 💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md) label Jan 22, 2020
@IvanGoncharov IvanGoncharov changed the title [RFC][strawman] allow empty selections [RFC] allow empty selections Jan 22, 2020
@leebyron
Copy link
Collaborator

Thanks for pushing this! I think we've thought about this so many times over the years that it's time to get crisp about whether we want to do this or not. I think earlier proposals suggested allowing the subselection to be omitted, but that was rejected because it could also be an easy mistake, this variant is less likely to be confused in that way.

Some things that may help:

  • Can we collect any kind of useful data about the prevalence of { __typename } or the singleton bool? If this is quite rare, then we should probably be happy to leave the existing behavior. If it's somewhat common, then that's a good argument for this change.

  • Audit of effect on execution and validation. I think it should be close to as straightforward as you've defined it here, but we need to look out for places in both the spec and reference implementation where we say "empty" and mean "non-existent"

It would also be really great if you could capture this kind of context into an RFC document as a first step (in /rfcs) that explains the problem, the context, any collected data, this solution as well as others (like omitting the selection set).

@jhusain
Copy link

jhusain commented Jan 31, 2020

Want to call out that this would also make it easier to implement programs which transform Documents. For example federation might cause fields to be removed from a selection set and inserted into another query, making it easy to end up inadvertently creating an empty selection set. Furthermore Flow/TypeScript types doesn't catch empty selection sets either as you can't reject empty arrays with those type systems. Instead you end up with a runtime error.

@victorandree
Copy link

For what it's worth, I'd favor omitting the subselection entirely.

  • This is what "empty" currently means in the spec (cf "If {selectionType} is a scalar or enum: The subselection set of that selection must be empty")
  • query { event { location {} } } } is currently a syntax error, while query { event { location } } } is a validation error. Loosening validation errors seems like a smaller change than loosening syntax.
  • I don't think the cost of mistakingly omitting fields is that high. You'd just get an empty object back, instead of an error.

I think allowing empty object selections would raise the expectation to support empty object types (which is why I'm commenting on this issue, since I worked a bit on this, see #606). You'd open up GraphQL to "marker objects" as it'd remove concerns about having to "select fields down to scalar values". I think this would be a net positive but I think the issues are related.

Base automatically changed from master to main February 3, 2021 04:50
@leebyron leebyron force-pushed the main branch 4 times, most recently from e5d241d to 6c81ed8 Compare April 23, 2021 19:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
💭 Strawman (RFC 0) RFC Stage 0 (See CONTRIBUTING.md)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants