😘

Cloudflare D1をQueryBuilderで強化する

2023/02/24に公開

皆なさんはCloudflareD1を使っているでしょうか?
Cloudflareが提供しているSQLite互換のデータベースで現在ベータ版ですが、圧倒的な使いやすさで気に入っています。
ですが、まだ提供されて間もないこともあり、ORMなどのエコシステムが充実していません。SQLをバリバリ書ければ問題ないですが、Prismaなどを知っているとどうしてもそういった環境を求めてしまいます。
また、諸説ありですが僕は保守性のためにもQBやORMなどを導入したいと思っています。

前置きが長くなりましたが、今回はCloudflareD1をKyselyというQueryBuilderを使ってアクセスすることで比較的リッチなD1ライフを送る方法を紹介します。

デモ

下記のコードを利用して作成したシンプルなAPIです。HonoV3を使用しています。
https://github.com/inaridiy/hono-kysely-example

APIの仕様

GET /?limit=number&offset=number ユーザー情報の一覧取得
GET /:id 特定のIDのユーザーを取得
POST / 特定のユーザーを作成

デモURL

https://hono-kysely-example.inaridiy.workers.dev/
ID1のユーザーを取得する
ユーザー一覧を取得する

Kyselyとは

Typescript製のQueryBuilderで、knexというJavascriptのQueryBuilderを参考にしてつくられています。
特徴としてはセットアップがほぼ不要なこと、TSの保管が効きまくって気持ちいいことです。
さらに、Dialectというクラスを入れ替えることでありとあらゆるDBに接続できます。有名どころだとMySQL,SQLite,PostgreSQL,さらには少し前に話題になったSurrealDBなんかにも対応しているそうです。
また、公式のリストによればサードパーティ製でCloudflareD1対応のDialectもあるそうなのですが、数ヶ月前のD1のアップデート以降使えなくなっています。
なので、今回は更なるD1の変更も見越してD1対応のDialectを自作する方針で進めていきます。

D1対応のDialectを作成する

といっても難しいことをするわけではありません。D1は基本的にSQLite互換なのでライブラリが提供しているコードをかなり利用できます。
ただ、D1は現在Transactionに対応していないので、その部分はモックのみを実装します。

https://github.com/inaridiy/hono-kysely-example/blob/63571b15c38509cf662acbe1b8f1191df2c43002/src/D1Dialect.ts#L1-L100

これをKyselyに渡してあげるだけでD1をKyselyで操作できます。

const qb = new Kysely<Schema>({
    dialect: new D1Dialect({ database: c.env.DB }),
  });

....
const result = await qb.selectFrom("users")
	.where("id", "=", 1)
	.executeTakeFirst();
/*
{
"id": 1,
"name": "zenn",
"email": "zenn@zenn.zenn",
"password": "zenn",
"created_at": "2023-02-23 22:35:11",
"updated_at": "2023-02-23 22:35:11"
}
*/

終わりに

今回紹介したKyselyを使ってD1をアクセスする方法を使うと、ただでさえ便利なD1がさらに便利になってやばいです。
レッツD1ライフ!!!

Discussion