@stream
Grats allows you to define fields which return a single item at a time in order to be compatible with the @stream
directive. Simply define your field as returning an AsyncIterable<YourType>
.
Example
/** @gqlType */
class Viewer {
/**
* An "algorithmically generated" feed of posts.
*
* **Note:** Due to the extreme complexity of this algorithm, it can be slow.
* It is recommended to use `@stream` to avoid blocking the client.
* @gqlField
*/
async *feed(_: unknown, ctx: Ctx): AsyncIterable<Post> {
const rows = await DB.selectPosts(ctx.vc);
for (const row of rows) {
// Simulate a slow algorithm
await new Promise((resolve) => setTimeout(resolve, 500));
yield new Post(row);
}
}
}
This field could then be read using a query like this:
query ViewerFeedQuery {
viewer {
feed @stream {
id
title
content
}
}
}
See the Query.feed
field in our Example Production App for an end to end working example.
Enabling for your GraphQL Server
tip
You will likely need to enable support of @stream
in your GraphQL server library. See below for an example of enabling @stream
in Yoga.
import { createServer } from "node:http";
import { createYoga } from "graphql-yoga";
import { getSchema } from "./schema";
import { useDeferStream } from "@graphql-yoga/plugin-defer-stream";
const server = createServer(
createYoga({
schema: getSchema(),
plugins: [useDeferStream()],
}),
);
server.listen(4000, () => {
console.log("Running a GraphQL API server at http://localhost:4000/graphql");
});
See the server.ts
in our Example Production App for an end to end working example.