Integrating Kysely with Fuse
Kysely (opens in a new tab) is an option to access SQL databases in a type-safe way in Node.js. Fetching data from an SQL database with Kysely in Fuse allows you to avoid having to type any underlying source type.
Getting the TypeScript types for a table
For example, given a kysely
schema with a users
table:
import {
ColumnType,
Generated,
Selectable,
} from 'kysely'
export interface Database {
user: UserTable
}
export interface UserTable {
id: Generated<string>
name: string
}
export type User = Selectable<UserTable>
We can create a UserNode without having to manually type the shape of the users
table by using the User
type:
import { node, NotFoundError, addQueryFields } from 'fuse'
import { User } from './db';
export const UserNode = node<User>({
name: 'User',
async load(ids) {
// Query for the list of users with the `ids`
const result = await db.selectFrom('user').where('id', 'in', ids).selectAll().execute()
return ids.map((id) => result.find((x) => x.id === id) || new NotFoundError('Could not find user.'));
},
fields: (t) => ({
name: t.exposeString('name'),
}),
})
Paginated lists
Creating a paginated list with t.list
requires returning both the list of nodes and the total count of nodes.
Here is what that would look like with Kysely;
addQueryFields((t) => ({
users: t.list({
type: UserNode,
nullable: false,
args: {
offset: t.arg.int(),
limit: t.arg.int(),
},
resolve: async (_, args) => {
const offset = args.offset || 0
const limit = args.limit || 10
const [totalCount, paginatedUsers] = await Promise.all([
// Get the total count of users as an int
db.selectFrom('user').select([
b => b.fn.countAll().as('count')
]).execute()
// Get the list of users based on the limit and offset
db.selectFrom('user').limit(limit).offset(offset)
])
return {
nodes: paginatedUsers,
totalCount: totalCount[0].count,
}
},
}),
}))