Open12
自社サービスのバックエンドを Go から TypeScript へ切り替えるための整理
切り替える理由
- 自社の主力製品で利用している技術(WebRTC / WebTransport)がブラウザベースのため TypeScript を利用する
- Go を採用したのは sqlc が使いたかったという理由
- sqlc-gen-typescript が出てきたのでもう Go を使う理由がなくなった
- 自社サービスチーム全員が Go にまったく興味が無い
- sqlc 自体は便利
- そもそも自社に Go への興味がある人がいない
- 自社サービスの規模ではボトルネックになるのはデータベースであって言語ではない
- もしアプリでスケールが必要なときは Rust や Erlang/OTP に切り替えれば良い
- コネクションプールは PgBouncer を利用すればいい
- TypeScript からは 1 コネクション 1 接続で問題無い
- どうせフロントエンドでは TypeScript を書く
- 自社では React 一択
- 当たり前だが VS Code の TypeScript サポートは素晴らしい
- ChatGPT や GitHub Copilot は TypeScript に詳しい
- すでに BFF を Cloudflare Workers + Remix で 2 年運用してきてあまり困っていない
- SQL などを引く Go で API を書いている部分を Remix 側に吸収する
- Remix から PostgresSQL や Meilisearch 、ClickHouse を利用する
- Remix は良い
- Biome, toolchain of the web は良い
- fast-check は良い
懸念
- 依存がめちゃくちゃ多くなる
- ライブラリ依存が多いの本当に好きじゃない
- 依存によるセキュリティリスク
- 正直回避できる気がしない
- Dependabot さん頼り
- 例外をできるだけ避けたい
- 例外難しすぎる
- Result 型を導入する
sqlc を採用した感想
- ORM を覚えたくない、SQL を覚えたいというモチベーションだったが、結果最高だった
- PostgreSQL で利用する前提だった事もあり、困ることがかなり少なかった
- 一番めんどくさかったのは pgx/v4 から pgx/v5 移行
- 自分のような SQL 初心者にとって SQL をコンパイルしてチェックできる仕組みは素晴らしい
- 共通語としての SQL は本当に最高
- sqlc 以外を今後利用するつもりは無いくらいに最高だった
技術選定
ランタイム
- Cloudflare Workers
- 採用
- 今まで運用してきてあまり困ってはいない
- ただログ周りはかなり不便
- Logpush 使っていきたい
- Tail Workers を使っていきたい
- wrangler のアップデートが頻繁で、バグに苦しめられることある
- 圧倒的な安さ
- Deno
- 期待
- Deno Deploy が良さそうに見える
- ログ周りがどうなのかが気になる
- 価格面で Cloudflare Workers にまけてる
- Deno KV では sqlc が使えない
- Node.js
- 不採用
- ローカル開発や CI はイイが運用は避けたい
- Node.js を自前で運用することはない、あくまでローカル用という認識
- Bun
- 不採用
- 未知数
- 破壊的変更が多そう
Remix
- remix-run/remix: Build Better Websites. Create modern, resilient user experiences with web fundamentals.
- sergiodxa/remix-auth: Simple Authentication for Remix
- airjp73/remix-validated-form: Form component and utils for easy form validation in remix
- colinhacks/zod: TypeScript-first schema validation with static type inference
PostgreSQL
-
https://www.npmjs.com/package/pg
- 採用
- 実績的には圧倒的に pg か
- Cloudflare で使うなら pg 一択と思って良さそう
-
https://www.npmjs.com/package/postgres
- 不採用
- トランザクションの書き方が好み
- バグで Cloudflare Workers だとエラーになる
ClickHouse
- ClickHouse/clickhouse-js: Official JS client for ClickHouse DB
-
https://clickhouse.com/docs/en/integrations/language-clients/javascript
- 普通に Cloudflare Workers でも動く
Meilisearch
sqlc-gen-typescript
- https://github.com/sqlc-dev/sqlc-gen-typescript
-
https://github.com/voluntas/sqlc-gen-ts-template
- 最低限は検証済み
-
Vitest と Testcontainers を利用したテストの実行もできる
- SQL の E2E テスト本当に便利
S3 クライアント
Base32
Slack クライアント
UUID 生成
-
https://developers.cloudflare.com/workers/runtime-apis/web-crypto
- Cloudflare Workers では Web Crypto 準拠で
crypto.randomUUID
が用意されてる
- Cloudflare Workers では Web Crypto 準拠で
- Node.js でも同一
OIDC
JWT
テスト
デプロイ
- コスト重視
- 安くて安定してること
- Go と Linode (Akamai Connected Cloud) の場合は最低でも $20/月かかる
- NodeBalancers $10/月
- Let's Encrypt を利用した証明書の更新が大変大変めんどくさそう
- Cloudflare Proxy 経由でオリジン証明書を利用する方向なら許容範囲
- Nanode 1 GB $5/月 x2
- NodeBalancers $10/月
- ClickHouse と PostgreSQL に繋げられるのが必須条件
- Cloudflare Workers はコレを満たしている
Cloudflare Workers
-
採用
-
月 $5
-
1000 万リクエスト/月
- 100 万リクエスト/$0.30
-
3000 万 CPU ミリ秒/月
- 100 万 CPU ミリ秒/$0.02
-
勝手にスケールしてくれるのは本当に便利
-
価格面を考えると圧倒的に Cloudflare Workers
- HTTP/3 も利用できる
- FW も気軽に利用できる
- ZeroTrust も利用できる
-
GitHub Actions を利用したデプロイも嬉しい
-
ClickHouse は HTTP ベースなので TCP Socket 経由で通信できるようにしてほしい
Deno Deploy
- 期待
- 月 $20
Fly.io
- 不採用
- 未調査
- 価格が別に安くない
Linode (で自前運用)
- 不採用
- Go と同じ構成になり最低でも $20 / 月
- スケールアウトがめんどくさいので、基本スケールアップになりそう
使ってみたい
-
Baselime - Observability and Error-tracking Platform
- Cloudflare に買収されて無料?で使えるようになった
- Cloudflare Workers との相性がよさそう
- Cloudflare Workers へ簡単に組み込めるようになった
- 今は Sentry を利用しているが使いこなせてるわけではないので移行する
PostgreSQL
- RDB はマネージド以外は採用しない
- sqlc は PostgreSQL との相性が良い
- OLAP は ClickHouse を利用する
- プールは PgBouncer と同等の仕組みが欲しい
- https://github.com/pgbouncer/pgbouncer
- Cloudflare Workers であれば Hyperdrive で良さそう
サービス
-
Timescale, Your Mature Postgres Cloud | Timescale
- 継続利用
- 今は Managed Service for TimescaleDB を利用してる
- 安定して利用できている
- Timescale Cloud の日本リージョンができた
- 円安の影響もあり高い
- これはしょうがない
- 将来性に不安があると感じている
- TSDB としては別に性能がでない
- 期待する機能や性能は ClickHouse が解決してくれることは検証済み
- PgBouncer 付き
- Prometheus Exporter 付き
-
Neon — Serverless, Fault-Tolerant, Branchable Postgres
- 検証環境用として採用
- 商用環境向けでなければ採用して良さそう
- 日本リージョンが無い
- シンガポールリージョンはある
-
Supabase | The Open Source Firebase Alternative
- 不採用
- 未調査
-
Data platform for PostgreSQL - Xata
- 不採用
- 日本リージョンが無い
-
AlloyDB for PostgreSQL | Google Cloud
- 不採用
- 未調査
- 価格が厳しそう
-
YugabyteDB. The Distributed SQL Database for Mission-Critical Apps
- 未検証
-
pgEdge Fully Distributed PostgreSQL
- 未調査
-
Managed Databases | Worry-free Database Hosting | Akamai
- 採用予定
- 提供開始待ち
データベースを含めた構成
- Remix
- Cloudflare Workers
- pg
- https://github.com/brianc/node-postgres
- Cloudflare Workers の場合は 1 connection 1 client で問題なさそう
- Hyperdrive がプールを持ってくれる
- PostgreSQL
- Managed service for TimescaleDB
- neon.tech
- Linode Postgres
- まだリリースされていない
- sqlc-gen-typescript
- @clickhouse/client-web
- https://github.com/ClickHouse/clickhouse-js
- ClickHouse Cloud
-
https://github.com/meilisearch/meilisearch-js
- 自前 Meilisearch
sqlc-gen-typescript
別にまとめてある。
- https://zenn.dev/shiguredo/articles/sqlc-gen-typescript
- https://github.com/voluntas/sqlc-gen-ts-template
Hyperdrive
- Hyperdrive がかなり良い。コネクションプールを持っているのも良い
- wrangler.toml には Hyperdrive の id を指定するだけ
- wrangler dev の時は localConnectionString を利用してくれる
- CA 証明書には非対応
$ pnpm exec wrangler hyperdrive create $NAME \
--connection-string="postgres://{user}:{password}@{host}:{port}/{database_name};"
node_compat = true
[[hyperdrive]]
binding = "HYPERDRIVE"
id = "a76a99bc342644deb02c38d66082262a"
localConnectionString = "postgres://user:password@localhost:5432/{databasename}"
# hyperdrive 作成時に指定した connection string が利用される
$ pnpm exec wrangler --remote
# localConnectionString が利用される
$ pnpm exec wrangler dev
Remix + Cloudflare Workers + pg + sqlc-gen-typescript + Hyperdrive + PostgreSQL 検証
-
ローカルから Hyperdrive 経由で docker compose で上げた Postgres へ接続する
pnpm exec wrangler dev ./server.ts
-
▲ [WARNING] Hyperdrive does not currently support 'wrangler dev' in local mode at this stage of the beta. Use the '--remote' flag to test a Hyperdrive configuration before deploying.
と出るが普通にいける
-
ローカルから Hyperdrive 経由で neon のシンガポールに上げた Postgres へ接続する
pnpm exec wrangler dev --remote ./server.ts
- デプロイして Hyperdrive 経由で neon のシンガポールに上げた Postgres へ接続する
pg
-
https://node-postgres.com/features/connecting#connection-uri
- connectionString での接続
-
https://node-postgres.com/features/transactions
- TX 使う時は pool.query は使わない
- pool.connect で取得した client を使って client.query を呼ぶ
- try/catch の finaly で client.release() を忘れないこと
Cloudflare Workers + Hyperdrive で利用する場合は pool は利用せず、普通に client を利用するで良さそう。
Cloudflare Workers
- セッション管理を KV にするか DO にするか
- KV で困らないとは思う
- D1 使うかどうか
- 管理画面用のキャッシュテーブルとして使うのはあり
- Cloudflare Workers は利用するができるだけロックインされないようにしたい
- とはいえ便利な機能は使っていく
-
https://developers.cloudflare.com/workers/configuration/versions-and-deployments
- デプロイのバージョニングができる
- まずはアップロードしておいて、好きなタイミングでデプロイとかができる
- まだベータ版
-
https://developers.cloudflare.com/workers/runtime-apis/rpc
- service binding を利用して別の worker の関数を気軽に呼べるようにする仕組み
- Go 部分を別 worker にしてしまい RPC を使って書き換えるというのもありかもしれない
- 少しずつ置き換えて行けそう
- Cloudflare Pages -> Cloudflare Workers という構成を取りやすくなった
- 参考
Neon
- 無料検証サービスのバックエンドには十分そう
- Neon — Serverless, Fault-Tolerant, Branchable Postgres
- PostgreSQL マネージドサービス
-
https://neon.tech/pricing
- 価格がお安い
- $ 19 は素晴らしい
- もし商用サービスで使うなら $69 かな
- 日本リージョンがなくて、シンガポールリージョン
- Hyperdrive の強みがでそう
- 日本リージョンきたらスゴイ使う人増えそう
- 管理画面はとても使いやすい
- 最大同時接続数 10,000
- 無料プランでもそうらしくて、衝撃
- ダッシュボードが充実していて参考になる
ClickHouse
-
https://clickhouse.com/docs/en/integrations/language-clients/javascript
-
@clickhouse/client-web
はCloudFlare workers
対応
-
- 早く sqlc が ClickHouse に対応して欲しい
- 有償プランで提供する方針らしいので楽しみ
検証
-
ローカルで docker compose で上げた ClickHouse にデータを追加
- HTTP なのでちょっと癖がある、正直 TCP Socket 使えるようにしてほしい
- デプロイで ClickHouse Cloud にデータを追加
sqlc と testcontainers を利用した E2E テスト
外形監視
-
https://developers.cloudflare.com/health-checks/
- Cloudflare ビジネスプランを契約しているので利用できる
- Slack のメール機能と連携させてる
- Cloudflare Pro プランだとちょっと厳しいか
- 将来的に Pro かフリーに戻す予定なので悩ましい
- Cloudflare ビジネスプランを契約しているので利用できる
-
https://onlineornot.com/
- 良いお値段
- 最低 $50/月
-
https://github.com/prometheus/blackbox_exporter
- Vutlr などから監視
- VictoriaMetrics へは Tailscale で送る