今年はプログラマーの仕事はぐっと減らし、リモートで週2,3日稼働で可能な範囲で受けています。ちょうどfluct時代にお世話になったもっちーさんが独立してさっそく困っているということで、お手伝いをしてました。【PR】もっちーさんはお手伝いを募集中!
いまts, hono, hono-rpc, zod, prisma, cloudflare worker, d1あたりのstackで開発しているが、まるで雰囲気でやっている(でもなんとなかっている
— トミール (@tomita) July 21, 2025
その後1年ほどやってみての所感を放流しておきます。
Cloudflare
Cloudflareは以前から好き。SimpleというよりEasyなのだがよくできてる。めんつゆ最高。謎のテクノロジーでsqliteがエッジで動く
DuckDBを使いたくて(Betaの)Cloudflare Containers使ったが、npm run dev から裏でdocker build/runが走ってすんなり使え、「おお、wrangler.jsoncにBindingを記述したらコンテナがDIされてきた」と感心した。1
Hono
yusukebe氏ががんばってる流行りのフレームワーク。さすが困ることなく使える😀
OpenAPI定義をどちらでやるか
@hono/zod-openapi と hono-openapi を使う2パターンがあって名前も似てて検索結果も混じりやすい。標準honoのapi2 に乗っかる方が好みなので、middleware提供スタイルであるhono-openapiの方を利用した。とはいえ、実ハンドラーコードの前にどっかりopenapiの定義、その後どっかりzodの定義が重なるので見通しは微妙。
CIでopenapi.jsonを生成するのを入れてたが、ある時なぜかdescribeRoute()の記述が取れないハンドラーがあった。調べたら「onError()定義があるsub app」で起きるエッジケースだったようなので、PRを送った。※merge済
Prisma
型とスキーマ管理が欲しいし有名だから選択したけど…。若干後悔している。ORMはやっぱ自分の足元を撃ちますな。kyselyとかの方が良かったかなあ
現在、最新版がブロッカーになっていて辛い。あとバージョンあげるにしても、prisma, zod, hono-openapi, honoあたりまとめて。かつ、作成されたtype/clientを共用しているfront側アプリも全部まとめて上げるがんばりが必要でダルい
prisma generator(@prisma/generator-helper)は楽しい
protobufを思い出した。今回作るのがActive RecordっぽいCRUDハンドラーばかりだったので、まるっとgenereate。jsでゴリゴリtsを書くのおもしろい。DMMF構造体がもっと(リレーションの情報とか)メタ情報が取れれば良いのだけど、モデル名・テーブル名・フィールド名だけでもけっこうやりたいことはできる
CIでのファイルの生成時(つまりcloudflare workersとかwrangler devではない環境)ではcloudflare:workers moduleが読まれると動かないので、一部遅延読み込みにするなどをして対応したがもっといいやり方があるのかもしれない
const { getContainer } = await import('@cloudflare/containers')
実際こんな感じのgenerate祭り
┌─▶ D1 migrations
│
schema.prisma ──┼─▶ prisma client
├─▶ ERD
├─▶ zod schemata / types
└─▶ handlers(hono) ────▶ openapi.json
└─▶ api/README.md
package.jsonのscriptsでgenerateの依存順を管理するのに、npm-run-all2を使った
"scripts": {
...
"generate": "run-s generate:*",
"generate:cf-type": "wrangler types --env-interface CloudflareBindings",
"generate:schema-format": "prisma format",
"generate:schema-generates": "prisma generate",
"generate:api-openapi.json": "npx --yes tsx doc/openapi-generator.ts",
"generate:api-readme.md": "npx --yes openapi-to-md doc/openapi.json > doc/README.md"
},
D1 migrationをどちらでやるか
prismaを使う場合Cloudflare D1のマイグレーション管理のやり方は2パターンあるが、今回ターゲットがD1ということと、prismaのロックオンを避けたい気持ちでBのwranglerコマンドを使う方にした。
- A.
prisma migrateコマンド, _prisma_migrationsテーブルで管理 - B.
wrangler d1 migrateコマンド, d1_migrationテーブルで管理
具体的には、schema.prismaをいい感じにしたあと、こんなので差分をmigrationファイルとして出力させて(必要なら微調整)
npx prisma migrate diff --from-local-d1 --to-schema-datamodel schema.prisma --script > db/migrations/0002_aaaaa.sql
ローカルで適用して確認
find .wrangler/state/v3/d1/miniflare-D1DatabaseObject/ -type f -name '*.sqlite' -delete
npx wrangler --env test d1 migrations apply test-db --local