Add FAQ about @defer on fragments vs fields#774
Conversation
| ## 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.
@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.
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.