Async selections
Planning selections that depend on asynchronous request data
Pothos selections are synchronous by default. Set AsyncSelections: true when a selection or
relation query must await request data before returning its query options.
Async selections
Use the client and relations configured in Setup. The context method below supplies a preview size loaded asynchronously, for example from account settings:
const builder = new SchemaBuilder<{
DrizzleRelations: typeof relations;
AsyncSelections: true;
Context: {
previewSize: () => Promise<number>;
};
}>({
plugins: [DrizzlePlugin],
drizzle: {
client: db,
getTableConfig,
relations,
},
});With the opt-in, select functions, relation query callbacks, relatedCount where callbacks,
and the select and query callbacks of drizzleConnectionHelpers may be async. Without it they
are typed as synchronous, and an async callback is a type error.
Pothos waits for these callbacks before executing the planned query. t.relation, t.relatedCount,
t.drizzleField, t.drizzleConnection and t.relatedConnection settle their plan before the
resolver runs, and need no changes.
builder.drizzleObject('users', {
name: 'User',
fields: (t) => ({
previewPosts: t.field({
type: ['posts'],
select: async (args, ctx, nestedSelection) => {
return {
with: {
posts: await nestedSelection({
where: { published: true },
orderBy: { id: 'asc' },
limit: await ctx.previewSize(),
}),
},
};
},
resolve: (user) => user.posts,
}),
}),
});Await nested selections
await what nestedSelection returns before putting it in the selection, and the same for the
nestedQuery passed as the fourth argument of a t.relatedField select. A selection that
contains the promise itself will throw, and so will a select that returns while a nested
selection it started is still pending. Include the nested selection in the returned query to
load its data.
Connection helpers
Pass awaitSelections: true to drizzleConnectionHelpers(...).getQuery, and await the query it
returns. Without it, an async selection beneath the field throws, and whether there is one
depends on the incoming document rather than on the callback you wrote. A connection helper also
throws when its own select or query is async, whatever the document asked for:
select: async (args, ctx, nestedSelection) => {
return {
with: {
attachments: await attachments.getQuery(args, ctx, nestedSelection, {
awaitSelections: true,
}),
},
};
},awaitSelections is a per-call option, and is available whether or not the schema sets
AsyncSelections.
When AsyncSelections: true, also await a connection helper's resolve() before inspecting or
spreading its result: an async query callback makes resolution asynchronous. Returning its
result directly from a GraphQL resolver remains supported.
The connection-helper excerpt uses the Post attachments relation and attachments helper from
Connection helpers. Request-context
methods must be supplied by the application; they are not created by declaring the Context type.