Cloudflare Workers による FaaS・Cloudflare Workers KV による Key-Value Store を試してみた
CDN プロバイダとして知られる Cloudflare だが、最近以下のようなサービスを展開している。
- Cloudflare Workers : FaaS・Functions
- Cloudflare Workers KV : Key-Value Store・NoSQL
- Cloudflare Pages : Static Website Hosting
- Cloudflare Web Analytics : Web Analytics
いずれも無料枠があり、クレジットカード入力もなく無料で利用し始められるのが特徴。
今回はこの中の上2つ、FaaS と NoSQL サービスである、Cloudflare Workers および Cloudflare Workers KV を試してみる。
目次
- Cloudflare へのアカウント登録
- 仕様と制約
- CLI ツール「Wrangler」をインストールする
- Wrangler でログインする
- Workers プロジェクトを作成する
- ローカル実行してみる
- Cloudflare Workers に公開する
- KV を作成する
- Wrangler CLI で KV の参照・操作
- 開発環境用の KV を作る
- 開発環境用の KV に Wrangler CLI でアクセスする
- Workers スクリプトから KV を参照する
- ローカル開発環境で動作確認 (プレビュー用 KV と接続)
- 公開して実際に動作確認 (本番用 KV と接続)
- 以上
- 参考文献
Cloudflare へのアカウント登録
予め、Cloudflare のアカウントを登録しておこう。
普通に Sign Up するだけ。クレジットカード入力が必要なくて安心。
仕様と制約
Workers・Workers KV ともに、無料枠ではいくつかの制限事項がある。前述のとおりクレカ入力していないので、いきなり課金が発生することはないが、大規模なアプリを無料枠で動かそうとするのは無理があるので、よくよく注意してほしい。
初めに Workers の制限を確認する。
- Cloudflare Workers®
- Limits · Cloudflare Workers docs
- 配置できる Workers スクリプトは30個まで
- 1日10万リクエストまで
- 1リクエストあたり 10ms 以内に処理すること (同期処理にかかる時間らしい・有料版でも 50ms が上限)
- Workers のメモリは 128MB (コレは有料版でも同じ)
→ AWS Lambda などと比べるとメモリが少なく、実行時間の制約も厳しめ。ゴリゴリとバックエンド処理をやらせる用途には向かず、プロキシ的な利用がギリギリだろう。以下のサンプルコード集も参考に。
次に Workers KV の制限。
- Cloudflare Workers KV | Serverless Computing | Cloudflare
- KV - Limits · Cloudflare Workers docs
- 容量 1GB まで
- 1日あたり10万回の読み取り、1,000回の書き込みが上限
- 1つの Value に登録できるのは 25MB まで
読み書きの回数に上限があるので、リクエスト数の多いアプリのバックエンドとして使おうとすると、すぐレート制限に引っ掛かってしまうだろう。
CLI ツール「Wrangler」をインストールする
Workers プロジェクトはブラウザのダッシュボード上からでも作成できるが、ローカル開発環境が用意できたりして便利なので、Cloudflare が提供する公式 CLI ツールの Wrangler を使っていく。
npm でグローバルインストールすれば良いが、裏は Rust 製なので Cargo でもインストールできるみたい。
$ npm i -g @cloudflare/wrangler
$ wrangler --version
wrangler 1.17.0
Wrangler でログインする
続いて、wrangler login
コマンドを使ってログインする。
- Authentication · Cloudflare Workers docs
- WSL でセットアップする場合は、「Ubuntu」のウィンドウで実施すること。VSCode 統合ターミナルからだとブラウザが開かずコンソールが進まなかった
$ wrangler login
Allow Wrangler to open a page in your browser? [y/n]
y
💁 Opened a link in your default browser: https://dash.cloudflare.com/wrangler?【……】
⠒ Waiting for API token...
# ブラウザが開くので許可を進めていく
💁 Validating credentials...
✨ Successfully configured. You can find your configuration file at: /home/neo/.wrangler/config/default.toml
# ログイン成功・トークンが書かれたファイルが出来ているので確認する
$ cat ~/.wrangler/config/default.toml
api_token = "【API トークン】"
# ログインユーザを確認する
$ wrangler whoami
╭──────────────────────────────────────────────────────────────────────────────────────────────────╮
│ │
│ 👋 You are logged in with an API Token, associated with the email 'neos21@gmail.com'! │
│ │
╰──────────────────────────────────────────────────────────────────────────────────────────────────╯
+----------------------------+----------------------------------+
| Account Name | Account ID |
+----------------------------+----------------------------------+
| Neos21@gmail.com's Account | 【アカウント ID】 |
+----------------------------+----------------------------------+
こんな感じ。
試しに KV を作ってみるかと思ったけど、KV は Workers プロジェクトを作ってからでないと作成できなかった。KV は紐付けた Workers からのみ呼び出しができるようだ。
# KV から先には作れない
$ wrangler kv:namespace create practice
Error: wrangler.toml not found
Workers プロジェクトを作成する
というワケで、先に wrangler generate
コマンドを使って Workers プロジェクトを作る。
# Workers プロジェクトを作る。この時点では Publish はされておらずダッシュボードには何も出ない
$ wrangler generate practice
Creating project called `practice`...
Done! New project created /home/neo/practice
🕵️ You can find your zone_id in the right sidebar of a zone's overview tab at https://dash.cloudflare.com
🕵️ You can copy your account_id below
+----------------------------+----------------------------------+
| Account Name | Account ID |
+----------------------------+----------------------------------+
| Neos21@gmail.com's Account | 【アカウント ID】 |
+----------------------------+----------------------------------+
🕵️ You will need to update the following fields in the created wrangler.toml file before continuing:
- account_id
コマンドで指定した名前どおり、practice/
というディレクトリができ、その下に各種ボイラープレートファイルが生成されている。
プロジェクトに関連する情報は、wrangler.toml
という設定ファイルに書いていく。アカウント ID やゾーン ID など、クレデンシャルっぽい雰囲気の項目もあるのだが、これらは wrangler.toml
にベタ書きして GitHub 公開しても大丈夫。
- 参考 : whoami should display
account_id
· Issue #630 · cloudflare/wrangler - 参考 : wrangler.toml Secrets · Issue #17 · cloudflare/wrangler-action
コンソールに表示されていたアカウント ID を、生成された wrangler.toml
に記載する。他のファイルは適当に調整した。
wrangler.toml
name = "practice"
type = "javascript"
account_id = "07100c21a5c21a0afb93ab435ba46712"
workers_dev = true
route = ""
zone_id = ""
index.js
/**
* Main
*/
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
/**
* Response With Hello World Text
*
* @param {Request} _request Request
*/
async function handleRequest(_request) {
return new Response('Hello World', {
headers: { 'content-type': 'text/plain' }
});
}
ローカル実行してみる
ファイルが用意できたら、wrangler dev
コマンドでローカルに Workers を立ち上げてみる。
$ wrangler dev
💁 watching "./"
👂 Listening on http://127.0.0.1:8787
[2021-07-08 09:38:39] GET practice.neos21.workers.dev/ HTTP/1.1 200 OK
[2021-07-08 09:38:40] GET practice.neos21.workers.dev/favicon.ico HTTP/1.1 200 OK
http://127.0.0.1:8787/
にアクセスすると、Hello World
とレスポンスがあった。index.js
の内容に沿ってリクエストが処理され、レスポンスされていることが確認できた。
Cloudflare Workers に公開する
動作確認ができたら、wrangler publish
コマンドで実際に公開してみる。
$ wrangler publish
✨ Basic JavaScript project found. Skipping unnecessary build!
✨ Successfully published your script to
https://practice.neos21.workers.dev
コレで公開できた。https://practice.neos21.workers.dev/ にアクセスすると Hello World
とレスポンスがあった。
ブラウザで見られるダッシュボードにも、プロジェクトが表示されるようになった。初回表示までは2・3分待つ必要あり。
KV を作成する
続いて KV を作成していく。
$ wrangler kv:namespace create kv
🌀 Creating namespace with title "practice-kv"
✨ Success!
Add the following to your configuration file:
kv_namespaces = [
{ binding = "kv", id = "32d76002a7784decb07151acf413098b" }
]
「名前空間の名前」としては、プロジェクト名と指定した名前空間をハイフンで結合した、practice-kv
というモノになる。
後述するが index.js
内で参照する名前空間としては、この内の kv
部分だけ記述すれば良い。index.js
で変数名として使用するためか、名前空間にはハイフンが使えず、アンダースコアでしか区切れない。
ひとまず、何やらコンソールに「コレを追記しろ」と出力されているので、この内容を wrangler.toml
に追記しておく。
# Worker 名 : `https://【この Worker 名】.【アカウント名】.workers.dev/` で公開できる
name = "practice"
# `$ worker build` コマンドでのビルド方法を指定する・`javascript` にすると Webpack が使われる
type = "javascript"
# `webpack.config.js` を自前で用意した場合は `webpack_config` プロパティで指定する
# アカウント ID
account_id = "07100c21a5c21a0afb93ab435ba46712"
# `workers.dev` にデプロイする場合は `true` にする
workers_dev = true
# `workers.dev` ではなく独自ドメインで公開する際に指定する・`workers.dev` で公開する場合は空文字で良い
route = ""
# `workers.dev` で公開する場合は空文字で良い
zone_id = ""
# KV : ↓ コレを追記した
kv_namespaces = [
{ binding = "kv", id = "32d76002a7784decb07151acf413098b" }
]
Wrangler CLI で KV の参照・操作
Workers KV は原則、紐付けた Workers からしかアクセスできないのだが、ログイン済の Wrangler CLI であれば、wrangler.toml
の内容を参照しながら、KV にアクセスできる。
# 名前空間名を指定してキーをリスト表示する
$ wrangler kv:key list --binding 'kv'
[]
# JSON 配列っぽい値を `test` というキー名で登録する
$ wrangler kv:key put 'test' '[ { "id": 1, "text": "Hello World" } ]' --binding 'kv'
✨ Success
# 登録したキー名が見えた
$ wrangler kv:key list --binding 'kv'
[{"name":"test"}]
# 登録したデータが見えた
$ wrangler kv:key get 'test' --binding 'kv'
[ { "id": 1, "text": "Hello World" } ]
# この内容はダッシュボード上でも確認できる (= 実際にアップされている)
開発環境用の KV を作る
このままでも、wrangler publish
したスクリプトから当該 KV へのアクセスはできるのだが、wrangler dev
で立てたローカル開発環境からはこの KV が参照できない。
そこで、--preview
オプションを使用し、開発環境用の KV を別途作成する。
# 開発環境 (`wrangler dev`) 用にプレビュー KV を作る
$ wrangler kv:namespace create 'kv' --preview
🌀 Creating namespace with title "practice-kv_preview"
✨ Success!
Add the following to your configuration file in your kv_namespaces array:
{ binding = "kv", preview_id = "9f23b9bb89db4af7a2eca3230e50780f", id = "32d76002a7784decb07151acf413098b" }
ダッシュボードを確認すると、practice-kv_preview
という名前空間の名前で KV が生成されている。名前が違うだけで、KV の動作としては変わりないようだ。
コンソール出力されている内容を参考にして、wrangler.toml
の kv_namespaces
部分を次のように修正する。
kv_namespaces = [
{ binding = "kv", id = "32d76002a7784decb07151acf413098b", preview_id = "9f23b9bb89db4af7a2eca3230e50780f" }
]
最初に作成した KV の記述をそのままに、preview_id
プロパティを追加し、practice-kv_preview
の ID を記載している。
開発環境用の KV に Wrangler CLI でアクセスする
Wrangler CLI でプレビュー環境にアクセスするには、次のように --preview
を付けながら操作すれば、先程試したコマンドと変わらずに KV が操作できる。
# 名前空間名を指定してキーをリスト表示する (`--preview` オプションだけ追記していることに注意)
$ wrangler kv:key list --binding 'kv' --preview
[]
# `practice-kv` の方には先程データを投入したが、`practice-kv_preview` にはまだ何もデータが入っていないので、キー一覧も空になっている
# JSON 配列っぽい値を `test` というキー名で登録する
$ wrangler kv:key put 'test' '[ { "id": 1, "text": "Hello World Preview" } ]' --binding 'kv' --preview
✨ Success
# キーが追加されている
$ wrangler kv:key list --binding 'kv'
[{"name":"test"}]
# 登録されたデータが確認できるが、`practice-kv` とは異なる値であることが分かる
$ wrangler kv:key get 'test' --binding 'kv'
[ { "id": 1, "text": "Hello World Preview" } ]
# この内容はダッシュボード上でも確認できる (= 実際にアップされている)
Workers スクリプトから KV を参照する
Wrangler CLI から KV の参照・操作ができたので、いよいよ Workers スクリプトを修正し、Workers から KV を参照・操作できるようにしていく。
index.js
/**
* Main
*/
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
/**
* Response With KV Value
*
* @param {Request} _request Request
*/
async function handleRequest(_request) {
const content = await kv.get("test"); // 変数 `kv` は Cloudflare Workers によって KV の名前空間名 `kv` がそのまま変数名に使われて自動的に定義されている
console.log(`Console Log : $${content}`);
return new Response(content, {
headers: { 'content-type': 'application/json' }
});
}
今回はまずはデータの取得だけ。いきなり kv.get()
とかいうメソッドを叩いているが、ココで出てくる kv
というのは、wrangler.toml
で binding = "kv"
と指定している、名前空間名である。コレがいきなりグローバル変数として定義された状態になっているので、そいつの get()
や put()
メソッドを呼んで、当該 KV を操作していくことになる。
ローカル開発環境で動作確認 (プレビュー用 KV と接続)
index.js
の内容を確認するため、wrangler dev
コマンドでローカル開発環境を起動する。wrangler.toml
ファイルの preview_id
指定により、プレビュー用 KV に接続していることが分かる。
$ wrangler dev
💁 watching "./"
👂 Listening on http://127.0.0.1:8787
# ブラウザで <http://127.0.0.1:8787> にアクセスしてみる
Console Log : $[ { "id": 1, "text": "Hello World Preview" } ]
[2021-07-08 12:00:46] GET practice.neos21.workers.dev/ HTTP/1.1 200 OK
公開して実際に動作確認 (本番用 KV と接続)
続いて wrangler publish
で公開する。
$ wrangler publish
✨ Basic JavaScript project found. Skipping unnecessary build!
✨ Successfully published your script to
https://practice.neos21.workers.dev
https://practice.neos21.workers.dev/ にアクセスすると、先程までは Hello World
とボイラープレートファイルの内容を答えていたが、今度は [ { "id": 1, "text": "Hello World" } ]
とレスポンスがあった。
ココで注目したいのは、Publish すると、kv_preview
ではなく kv
からデータから読み取られている点だ。
以上
Cloudflare Workers および Cloudflare Workers KV の初歩はココまで。今回作成した Workers のコードをコミットした GitHub リポジトリと、実際に本番公開している Workers の URL は次のとおり。最新のコードの内容は、次回の記事で紹介するウェブアプリ向けのモノになっているので、過去のコミットログを遡って確認してみてほしい。
- Neos21/practice-cloudflare-workers: Practice Cloudflare Workers
- https://practice.neos21.workers.dev/
次回は Cloudflare Pages でデプロイしたフロントエンドから、この Cloudflare Workers を呼び出して KV を利用するアプリを作ってみる。
参考文献
その他参考にしたページは以下。
- cloudflare/kv-asset-handler: Routes requests to KV assets
- JS 内で KV の操作を簡単にする公式の npm パッケージ
- Building a To-Do List with Workers and KV
- signalnerve/cloudflare-workers-todos: A simple todo list application built with Cloudflare Workers and KV
- Workers で簡単な ToDo アプリを作っている例
- GET リクエスト時は HTML をレスポンスし、PUT リクエスト時は KV のデータを更新するコードが紹介されている
- Cloudflare Workersのチュートリアルをやってみた