⚡️ Pro Feature ⚡️ This feature is bundled with GraphQL-Pro.
You can use @defer
and @stream
with GraphiQL, an in-browser IDE.
If you’re using the proposed incremental: ...
response syntax (proposal, Ruby support), you’ll need a custom “fetcher” function to handle the incremental: ...
part of the response. For example:
import { meros } from "meros"; // for handling multipart responses
const customFetcher = async function* (graphqlParams, fetcherOpts) {
// Make the initial fetch
var result = await fetch("/graphql", {
method: "POST",
body: JSON.stringify(graphqlParams),
headers: {
'content-type': 'application/json',
}
}).then((r) => {
// Use meros to turn multipart responses into streams
return meros(r, { multiple: true })
})
if (!isAsyncIterable(result)) {
// Return plain responses as promises
return result.json()
} else {
// Handle multipart responses one chunk at a time
for await (const chunk of result) {
yield chunk.map(part => {
// Move the incremental part of the response into top-level
// This assumes there's only one `incremental` entry
// which is currently true for GraphQL-Pro's @defer implementation
var newJson = {...part.body}
if (newJson.incremental) {
newJson.data = newJson.incremental[0].data
newJson.path = newJson.incremental[0].path
delete newJson.incremental
}
return newJson
});
}
}
}
// Helper for checking for a multipart response:
function isAsyncIterable(input) {
return (
typeof input === "object" &&
input !== null &&
(
input[Symbol.toStringTag] === "AsyncGenerator" ||
(Symbol.asyncIterator && Symbol.asyncIterator in input)
)
);
}
Hopefully a new GraphiQL version will support this out of the box; follow the issue on GitHub.