From 751eb2935e86b3215e2c95bdfc790a0755b2f780 Mon Sep 17 00:00:00 2001 From: Rob Richard Date: Wed, 2 Sep 2020 17:51:59 -0400 Subject: [PATCH 1/3] Add FAQ about @defer on fragments vs fields --- rfcs/DeferStream.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rfcs/DeferStream.md b/rfcs/DeferStream.md index 5524625ab..c3a12beb1 100644 --- a/rfcs/DeferStream.md +++ b/rfcs/DeferStream.md @@ -159,6 +159,11 @@ The GraphQL spec does not currently support object identification or consistency ### Can @defer/@stream increase risk of a denial of service attack? This is currently a risk in GraphQL servers that do not implement any kind of query limiting as arbitrarily complex queries can be sent. Adding `@defer` may add some overhead as the server will now send parts of the query earlier than it would have without `@defer`, but it does not allow for any additional resolving that was not previously possible. +## 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 would 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. 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. + # Additional material - [1] [Lee Byron on idea of @defer and @stream](https://www.youtube.com/watch?v=ViXL0YQnioU&feature=youtu.be&t=9m4s) From 1327007814583ad6ae3843f99f87c3766a51da2a Mon Sep 17 00:00:00 2001 From: Rob Richard Date: Wed, 2 Sep 2020 21:26:55 -0400 Subject: [PATCH 2/3] Update DeferStream.md --- rfcs/DeferStream.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rfcs/DeferStream.md b/rfcs/DeferStream.md index c3a12beb1..0c16c23bd 100644 --- a/rfcs/DeferStream.md +++ b/rfcs/DeferStream.md @@ -161,8 +161,8 @@ This is currently a risk in GraphQL servers that do not implement any kind of qu ## 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 would 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. 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. +### 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. # Additional material From aaf71e54971673deea009f31b27038261e89fafd Mon Sep 17 00:00:00 2001 From: Rob Richard Date: Wed, 4 Nov 2020 12:49:12 -0500 Subject: [PATCH 3/3] Update DeferStream.md --- rfcs/DeferStream.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rfcs/DeferStream.md b/rfcs/DeferStream.md index 0c16c23bd..9e25cc424 100644 --- a/rfcs/DeferStream.md +++ b/rfcs/DeferStream.md @@ -162,8 +162,13 @@ This is currently a risk in GraphQL servers that do not implement any kind of qu ## 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. +The first experimental implementation of `@defer` was in Apollo Server and only supported `@defer` on fields. When applying this to production code, we quickly found that most use-cases were to defer a group of multiple fields, and block the corresponding UI from rendering until all fields in the group have been resolved. This requires the client to track the loading state of each individual field, showing the loading indicator until it receives the asynchronous payloads for each field. Alternatively, a client could render the UI for each individual field as soon as it's ready. However, this could lead to a bad user experience, with the UI repainting and reflowing many times as the data is loaded. +By supporting `@defer` on fragments, the client is signaling to the server to return the results of the fields in the fragment, when the entire fragment has finished resolving. The client only needs to wait for this payload before rendering the corresponding UI. + +For these reasons, this proposal only supports `@defer` on fragment spreads and inline fragments. If only a single field needs to be deferred, an inline fragment with `@defer` can easily wrap the field. By not allowing `@defer` on fields, we hope to discourage bad user experiences caused by many fields loading independently, and provide an easy upgrade path from deferring a single field to deferring many fields. + +The GraphQL WG is not ruling out supporting `@defer` on fields in the future if additional use-cases are discovered, but it is no longer being considered for this proposal. # Additional material - [1] [Lee Byron on idea of @defer and @stream](https://www.youtube.com/watch?v=ViXL0YQnioU&feature=youtu.be&t=9m4s)