Reputation: 11358
I have a query like this in my React/Apollo application:
const APPLICATIONS_QUERY = gql`
{
applications {
id
applicationType {
name
}
customer {
id
isActive
name
shortName
displayTimezone
}
deployments {
id
created
user {
id
username
}
}
baseUrl
customerIdentifier
hostInformation
kibanaUrl
sentryIssues
sentryShortName
serviceClass
updown
updownToken
}
}
`;
The majority of the items in the query are in a database and so the query is quick. But a couple of the items, like sentryIssues
and updown
rely on external API calls, so they make the duration of the query very long.
I'd like to split the query into the database portion and the external API portion so I can show the applications
table immediately and add loading spinners for the two columns that hit an external API... But I can't find a good example of incremental/progressive querying or merging the results of two queries with Apollo.
Upvotes: 2
Views: 952
Reputation: 84657
This is a good example of where the @defer
directive would be helpful. You can indicate which fields you want to defer for a given query like this:
const APPLICATIONS_QUERY = gql`
{
applications {
id
applicationType {
name
}
customer @defer {
id
isActive
name
shortName
displayTimezone
}
}
}
`
In this case, the client will make one request but receive 2 responses -- the initial response with all the requested fields sans customer
and a second "patch" response with just the customer field that's fired once that resolver is finished. The client does the heavy lifting and pieces these two responses together for you -- there's no additional code necessary.
Please be aware that only nullable fields can be deferred, since the initial value sent with the first response will always be null. As a bonus, react-apollo
exposes a loadingState
property that you can use to check the loading state for your deferred fields:
<Query query={APPLICATIONS_QUERY}>
{({ loading, error, data, loadingState }) => {
const customerComponent = loadingState.applications.customer
? <CustomerInfo customer={data.applications.customer} />
: <LoadingIndicator />
// ...
}}
</Query>
The only downside is this is an experimental feature, so at the moment you have to install the alpha preview version of both apollo-server and the client libraries to use it.
See the docs for full details.
Upvotes: 2