⚡️ Pro Feature ⚡️ This feature is bundled with GraphQL-Pro.
@defer in queries, you have to:
@deferto your GraphQL schema
You can also see a full Rails & Apollo-Client demo.
GraphQL::Pro::Defer is included in
graphql-pro 1.10+, and it requires the new Interpreter runtime in
graphql 1.9+, so update your gemfile:
# 1.9+ for Interpreter gem "graphql", "~>1.9.0" # 1.10+ for `@defer` gem "graphql-pro", "~>1.10.0"
And then install them:
$ bundle update graphql graphql-pro
@deferto your schema
GraphQL::Pro::Defer to your schema as a plugin:
class MySchema < GraphQL::Schema # The new interpreter runtime (1.9+) is required: use GraphQL::Execution::Interpreter use GraphQL::Analysis::AST # Then add the directive: use GraphQL::Pro::Defer end
Many web frameworks have support for streaming responses, for example:
See below for how to integrate GraphQL’s deferred patches with a streaming response API.
To investigate support with a web framework, please open an issue or email
When a query has any
@defered fields, you can check for
if context[:defer] # some fields were `@defer`ed else # normal GraphQL, no `@defer` end
To handle deferrals, you can enumerate over
context[:defer], for example:
context[:defer].each do |deferral| # do something with the `deferral`, eg # stream_to_client(deferral.to_h) end
The initial result is also present in the deferrals, so you can treat it just like a patch.
Each deferred patch has a few methods for building a response:
.to_hreturns a hash with
errors:. (There is no
path:for the root result.)
.to_http_multipartreturns a string which works with Apollo client’s
.pathreturns the path to this patch in the response
.datareturns successfully-resolved results of the patch
.errorsreturns an array of errors, if there were any
.errors on a deferral will resume GraphQL execution until the patch is complete.
In this example, a Rails controller will stream HTTP Multipart patches to the client, in Apollo Client’s supported format.
class GraphqlController < ApplicationController # Support `response.stream` below: include ActionController::Live def execute # ... result = MySchema.execute(query, variables: variables, context: context, operation_name: operation_name) # Check if this is a deferred query: if (deferred = result.context[:defer]) # Use built-in `stream_http_multipart` with Apollo-Client & ActionController::Live deferred.stream_http_multipart(response) else # Return a plain, non-deferred result render json: result end ensure # Always make sure to close the stream response.stream.close end end
You can also investigate a full Rails & Apollo-Client demo
Read about client usage of