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

Add FAQ about @defer on fragments vs fields #774

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in 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