Documentation
Building your API (server)
Integrating data sources
Kysely

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,
      }
    },
  }),
}))