-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add FAQ about @defer on fragments vs fields #774
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Conversation
rfcs/DeferStream.md
Outdated
## Frequently Asked Questions | ||
|
||
### Why is `@defer` supported on fragments instead of fields? | ||
If there is a UI component that renders many fields which are deferred, it could be cumbersome to coordinate the loading state of all of those fields. By deferring all of the fields on a fragment, the component can render its fallback loading state until the fragment is loaded, without having to manage the individual state of many fields. If only a single field needs to be deferred, it can be wrapped in an inline fragment. Since there is an easy workaround, we do not plan to support `@defer` on an individual field as part of this proposal. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@robrichard Same can be said for @skip
and @include
.
I actually think we need to support it in fields to be consistent.
Especially since nothing prevents you from wrapping every individual component into separate fragments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that it isn't possible to defer delivery of a field value - to have the key present in the response but not its value. Therefore, the actual payload that has to be sent in this case - along with the label and path - must always be the same as if the field selection was wrapped in a deferred inline fragment. For example consider the following query, where both fields (id, name) are typed as non-null in the schema:
// HYPOTHETHICAL
{
user {
id
name @defer(...)
}
}
There is no way to defer only the value of name
, ie it is invalid to send a set of responses such as that below, since there is no legal value to send in the first payload for name
:
{
"data": {
"user": {
"id": "<userid>"
"name": ???? // <--- no legal value here, name is non-nullable
},
}
{
"data": "<username>",
"path": ["user", "name"],
"label": "...."
}
Instead, this must be treated as if the query was:
{
user {
id
... @defer(...) {
name
}
}
}
in which case the server can return a valid set of responses - note that data
and path
are different!:
{
"data": {
"user": {
"id": "<userid>"
// note 'name' not present here
},
}
{
"data": {
"name": "<username>",
},
"path": ["user"],
"label": "...."
}
I think it's worth considering that implementation-wise @defer
must always behave as if the user had deferred a parent inline fragment. If you're trying to work with a raw response, this likely isn't obvious and could lead to confusion.
I'm going to add more background here as discussed in the WG meeting |
@benjie @robrichard can we merge that? |
@andimarek yes this can be merged |
No description provided.