Cloudflare Workers + KV + honoで簡単なAPIサーバを作る
Cloudflare Workers + KV + honoで簡単なAPIサーバーを作ってみたくて、ebaというモックAPIを作成できるAPIサーバーを書いてみた。突然適当なメソッドと適当なURLで適当なレスポンスを返すAPIが欲しくなったときに使える。
使い方としては、1) 専用の名前空間を作って、2) 好きなエンドポイントを設定する、だけ。こんな感じ。
# 名前空間の作成。パスワードも適当に設定しておく。
$ curl -X POST 'https://eba.razokulover.workers.dev/' -H 'X-REQUEST-TYPE:register' -d '{"password": "xxxxxxxx"}'
{"namespace": "your-unique-namespace", "password": "xxxxxxxx"}
# エンドポイントの作成
# GET /hoge で {"msg": "Hello"} をjsonレスポンスで返してくれるエンドポイントを作る。
# ついでにmy-original-headerというカスタムヘッダーも返してくれるようにしてみる。
$ curl -X POST 'https://eba.razokulover.workers.dev/' \
-H 'X-NAMESPACE:your-unique-namespace' \
-H 'X-PASSWORD:xxxxxxxx' \
-H 'X-REQUEST-TYPE:create' \
-d '{"url": "/https/zenn.dev/hoge", "method": "GET", "statusCode": 200, "responseHeader": {"content-type": "application/json", "my-original-header": "XXX"}, "responseBody": {"msg": "Hello"}}'
{"message": "ok"}
これで名前空間とエンドポイントが作成された。あとは作成したエンドポイントを叩くだけ。X-NAMESPACE
の指定だけ常に必要になるので注意。
$ curl -X GET -H 'X-NAMESPACE:your-unique-namespace' -D - 'https://eba.razokulover.workers.dev/hoge'
HTTP/2 200
content-type: application/json
my-original-header: XXX
{"msg": "Hello"}
技術
今回利用した技術としては下記。
- 開発コマンド: wrangler2
- サーバ: Cloudflare Workers
- KVS: KV
- framework: hono
- 言語: TypeScript
- ビルド: esbuild
- テスト: jest
- テスト環境: miniflare
HTMLなページのあるwebアプリならPages + functions か Workers + Sites の構成から選ぶことになるが、今回はAPIサーバのみなのでWorkers単体での利用になっている。詳しくはPages + Funcitons なのか Workers + Sites なのかをみて。
あと以降は開発環境の設定・テスト環境の設定・デプロイ設定などのコーディング以外の部分の情報が少なめのところを簡単に書いておく。
開発環境設定
wrangler2のインストール
$ npm install -g wrangler
1.0ではなくcloudflare/wrangler2が入っていることを確認する。
init
$ wrangler init my-worker
KVの設定
KVの作成と設定
$ wrangler kv:namespace create "MY_KV"
$ wrangler kv:namespace create --preview "MY_KV"
// wrangler.toml
name = "my-worker"
main = "src/index.ts"
compatibility_date = "2022-05-15"
kv_namespaces = [
{ binding = "MY_KV", id = "yyyyyyyyyyyyyyyy", preview_id = "xxxxxxxxxxxxxxxxx" }
]
その他wrangler.tomlに指定できるオプションについてはConfiguration · Cloudflare Workers docsを読むと良い
テスト環境の整備
依存関係のインストール
$ npm i -D miniflare
$ npm i -D jest jest-environment-miniflare
$ npm i -D esbuild esbuild-jest
$ npm i -D @types/jest
[miniflare https://miniflare.dev/]はCloudflare Workersのローカルシミュレータ。wrangler2.0からはwrangler dev --local
とやると内部的にはminiflareが使われるようになっているらしい。明示的にinstallしているのはjestのtestEnvironment
としてminiflareを使用したいので。[jest-environment-miniflare https://github.com/cloudflare/miniflare/tree/master/packages/jest-environment-miniflare]も同じくtestEnvironment
用。
[esbuild https://esbuild.github.io/]は高速なビルドツール。wrangler2.0から内部で使われるようになっている。[esbuild-jest https://github.com/aelbore/esbuild-jest]はjestのesbuild用トランスフォーマー。
jestの設定
// jest.config.js
module.exports = {
testEnvironment: "miniflare",
testMatch: [
"**/test/**/*.+(ts|tsx|js)",
"**/src/**/(*.)+(spec|test).+(ts|tsx|js)",
],
transform: {
"^.+\\.(ts|tsx)$": "esbuild-jest",
},
};
tsconfig.jsonにjestの@typesの追加
// tsconfig.json
{
"compilerOptions": {
...
"types": [
"@cloudflare/workers-types",
"@types/jest" // <- 追記
]
...
}
}
package.jsonのscriptsにコマンド追加
// package.json
{
...
"scripts": {
"start": "wrangler dev",
"publish": "wrangler publish",
"build": "esbuild --bundle --outdir=dist ./src/index.ts", // <- 追加
"dev": "wrangler dev --local", // <- 追加
"test": "npx jest --verbose" // <- 追加
},
...
}
開発
ローカルで開発サーバを立ち上げる
$ npm run dev
サーバーを書く
サンプルがてらKVを使った簡単なサーバー。MY_KV
というネームペースがwrangler.tomlでWorkerにバインドされているのでdeclare
してしまえばスクリプトからput/getができる。
declare const MY_KV: KVNamespace;
addEventListener('fetch', (event: FetchEvent): void => {
event.respondWith(this.handleEvent(event))
})
async function handleRequest(request) {
const key = `${request.method}`
await MY_KV.put(key, `Hello, ${request.method}`)
const value = await MY_KV.get(key)
return new Response(`message: ${value}`, {
headers: { 'content-type': 'text/plain' },
});
}
参考
実際の開発のコードはhonoのexmaplesを参考にした。
自分のコードも汚いけど参考にはなるかも。
デプロイ
wrangler publish
とコマンドを叩くだけでデプロイ自体は簡単にできるんだけどせっかくなのでGitHub Actionsの設定もやった。
GitHub Actionsの設定
下記環境変数をGitHubに設定する。
-
CF_API_TOKEN
- API Tokensで発行。Edit Cloudflare Workersというテンプレからほぼデフォルトのまま作成。
-
CF_ACCOUNT_ID
- Cloudflare WorkersのダッシュボードのTOPからコピー。
.github/workflows/deploy.yml
は下記の通り。
name: Deploy
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
name: Deploy
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: "14"
cache: "npm"
- name: Install Dependencies
run: npm ci
- name: Build
run: npm run build
- name: Publish
uses: cloudflare/wrangler-action@2.0.0
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
env:
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
その他
environmentsの設定
Workersの各種環境をprod/stg/devのような感じで分けて設定することができる。今回はやらなかったけど、ちょっと真面目に使うつもりなら設定したほうが良さそう。
KV以外のストレージ
Durable Objectsという最低$5の一貫性やトランザクションのサポートのあるグローバルなKVSがある。今回は使わなかったけどKVだとwriteの反映に最大60秒かかったりして使いづらいこともあるのでちょっと真面目に使うつもりなら導入を検討したほうが良さそう。
来月以降はD1のbetaも来そう。SQLiteが使えるとより用途の幅が広がりそう。
wrangler1ではなくwrangler2を使う
wranglerはついこの前wrangler2がリリースされた。miniflareというローカルシミュレータが組み込まれていたり何かと使いやすくなっているので特にこだわりなければwrangler2を使うと良い。
honoの開発が活発すぎる問題
ほぼ毎日何かしら開発されていて、マイナーバージョンレベルだとアップデートがガンガン行われている。これ事態別に悪いことではないんだけどREADMEやexampleのアプリとの乖離がちょくちょく発生したりして最初混乱した。コードもそんなに大きいものではないので困ったらソースコードを読むほうが早い。
参照リポジトリが少ない
wrangler2系を使った参照実装になるようなWorkersのリポジトリがそんなに多くないのでここどう書いたら良いのだろう???というような時に我流になりがち。まぁまだこの前正式にリリースされたばかりだから仕方ないけど。公式DocsにもExampleが増えていくといいなと思った。
wrangler.tomlをリポジトリに含めていいのか
wrangler.tomlにはCloudflare Workersに関する設定を記述するのだが、account_idやkvのidなどを含めてそのままGitHubに公開しても良いのかがわからなかった。account_idに関しては含めても良いというissueコメントを発見したが、kv_namespaceのidなんかも公開してしまっていいのだろうか。他の人たちのwrangler.tomlをみてみるとそのままidを含めている人もいればwrangler.example.tomlのような形で公開していない人もいた。API Tokenさえ漏れなければ別に公開していても大丈夫なんだろうとは思うけどこの辺はドキュメントに書いて欲しいなと思った。自分は現状クレカも登録してないし課金されることもないと思うのでwrangler.tomlの情報はGitに含めて公開してある。そもそも趣味アプリなので困ったらすぐ消せば良いし。
リソース
-
Cloudflare Workers documentation · Cloudflare Workers docs
- Workersの公式Docs。Workers関連で困ったらここ。ここより詳しく書いてあるリソースはまだないと思う。
-
Cloudflare Workers メモ
- 時雨堂の中の人のscrapメモ。Workersをキャッチアップしていくときに必要になる知識やハマりどころなんかが割と網羅的にまとめられておりありがたい。余談だけどvoluntasさんには何故かTwitterをブロックされていてちょっと面白かった。
-
honojs/hono: Ultrafast web framework for Cloudflare Workers. Fast, but not only fast.
- hono。公式DocsのQuick Startにも掲載されているWorkersのweb framework。hono情報はリポジトリが1番詳しい、というかそれ以外の情報源がほぼないのでここをみるしかない。
Discussion