Type variants
Variants
It is often useful to be able to define multiple object types based on the same table. This can be
done using a feature called variants. The variants API consists of 3 parts:
- A
variantoption that can be passed instead of a name ondrizzleObjects - The ability to pass an
ObjectRefto thetypeoption oft.relationand other similar fields - A
t.fieldmethod that works similar tot.relation, but is used to define a GraphQL field that references a variant of the same record.
// Viewer type representing the current user
export const Viewer = builder.drizzleObject('users', {
variant: 'Viewer',
select: {},
fields: (t) => ({
id: t.exposeID('id'),
// A reference to the normal user type so normal user fields can be queried
user: t.variant('users'),
// Adding drafts to View allows a user to fetch their own drafts without exposing it for Other Users in the API
drafts: t.relation('posts', {
query: {
where: {
published: false,
},
orderBy: {
updatedAt: 'desc',
},
},
}),
}),
});
builder.queryType({
fields: (t) => ({
me: t.drizzleField({
// We can use the ref returned by builder.drizzleObject to define our `drizzleField`
type: Viewer,
resolve: (query, root, args, ctx) =>
db.query.users.findFirst(
query({
where: {
id: ctx.user.id,
},
}),
),
}),
}),
});
builder.drizzleNode('users', {
name: 'User',
fields: (t) => ({
firstName: t.exposeString('firstName'),
// This field will resolve to the Viewer type, but be set to null if the user is not the current user
viewer: t.variant(Viewer, {
isNull: (user, args, ctx) => user.id !== ctx.user?.id,
}),
}),
});A t.variant field can have a select of its own. It is planned along with the variant's
type-level selection when the variant is queried through that field:
builder.drizzleNode('users', {
name: 'User',
fields: (t) => ({
viewer: t.variant(Viewer, {
// loaded with the row when `viewer` is selected
select: { columns: { email: true } },
isNull: (user, args, ctx) => user.id !== ctx.user?.id,
}),
}),
});Two variants of one table selected for the same row have their type-level selections merged into a single query, which can fail if they disagree. See Conflicting selections between variants.