Skip to content

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

Merged
merged 3 commits into from
Apr 4, 2021
Merged

Conversation

robrichard
Copy link
Contributor

@robrichard robrichard commented Sep 2, 2020

No description provided.

## 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.
Copy link
Member

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.

Copy link
Contributor

@josephsavona josephsavona Sep 4, 2020

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.

@IvanGoncharov IvanGoncharov added the 📣 RFC document PR creates or changes document inside "rfc" folder label Sep 3, 2020
@robrichard
Copy link
Contributor Author

I'm going to add more background here as discussed in the WG meeting

@andimarek
Copy link
Contributor

@benjie @robrichard can we merge that?

@robrichard
Copy link
Contributor Author

@andimarek yes this can be merged

@benjie benjie merged commit 65fd324 into graphql:main Apr 4, 2021
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
📣 RFC document PR creates or changes document inside "rfc" folder
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants