くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Cloudflare Workersに入門する

ずっと気になっていた、Cloudflare Workers
そろそろ入門しようと、ドキュメントを読んでみたときの備忘録(*´ω`*)

Cloudflare Workersとは

このスライドがわかりやすい

ざっくりいうと、

  • ユーザに近い距離にあるサーバ(エッジサーバ)で動く
  • サーバレスな処理(APIとかWebアプリとか)

正確ではないけど、HTTPリクエストを受け付ける
AWS LamdaとかGCP Cloud Functionsとかみたいな感じ

Cloudflare Workersの特徴

なんといっても安くて速いのが魅力。定期実行もできる
1日10万リクエストまで無料なので、大体は大丈夫

一方で、workerサイズが3MBまで、処理は10msまでなど、
制限が多いので、ちょっとしたものに利用する形

なにができるのか

ユースケースとしてはこの記事がわかりやすい
リバースプロキシ的な事ができる

たとえば、

  • リクエストの中継。カスタムドメインとか
  • HTMLのリライト/書き換え
  • 動的コンテンツのキャッシュ操作

などなど

とりあえず、Hello World

ここを見ながら試してみる

Worker Projectの作成

プロジェクトの作成は、C3(create-cloudflare-cli)というコマンドラインツールでやるっぽい

$ pnpm create cloudflare@latest my-first-worker

いろいろ聞かれるけど、とりあえず、exampleのを選ぶ

╭ Create an application with Cloudflare Step 1 of 3
│
├ In which directory do you want to create your application?
│ dir ./my-first-worker
│
├ What would you like to start with?
│ category Hello World example
│
├ Which template would you like to use?
│ type Hello World Worker
│
├ Which language do you want to use?
│ lang TypeScript
│
├ Do you want to use git for version control?
│ yes git
│
├ Do you want to deploy your application?
│ no deploy via `pnpm run deploy`
│
╰ Done 

生成されるProjectはこんな感じ
テスト(vitest)も用意してくれる

my-first-worker/
├── src
│   └── index.ts
├── test
│   ├── index.spec.ts
│   └── tsconfig.json
├── package.json
├── pnpm-lock.yaml
├── tsconfig.json
├── vitest.config.mts
├── worker-configuration.d.ts
└── wrangler.toml

開発サーバの起動

開発サーバの起動はこれでOK

$ pnpm dev

package.jsonの中身はこんな感じで、
Workers用のCLI(Wrangler)を利用する感じ

"scripts": {
  "deploy": "wrangler deploy",
  "dev": "wrangler dev",
  "start": "wrangler dev",
  "test": "vitest",
  // wrangler.tomlにbindingsを追加したときに利用する
  "cf-typegen": "wrangler types"
},

生成されたコードを見る

export default {
  // fetch() handlerが、HTTPリクエストを受け取る関数
    async fetch(request, env, ctx): Promise<Response> {
        return new Response('Hello World!');
    },
} satisfies ExportedHandler<Env>;

fetch() handlerが、HTTPリクエストを受け取る関数になっていて、
その中に処理を書いていく感じ

ほかにも、定期実行用のScheduled Handler(scheduled())などもある

設定ファイル(wrangler.toml)を見る

wrangler.tomlにWorkersの設定を書くっぽい

主には、このあたり

secretsは、wranglerコマンドで設定する感じ
($ wrangler secret put <KEY>)

利用できるAPI

Workersは、Node.jsではなく、V8で実行するので、
使えるAPIがちょっと違うので注意が必要
(Node.jsとの互換性があるのもある)

たとえば、console系だと、こんな感じで対応状況が記載されている

とりあえず、よく使いそうなのをPickup

Request

fetch() handlerrequest

Fetch APIRequestと同じ

リクエストを書き換えたい場合は、こんな感じらしい

export default {
  async fetch(request, env, ctx) {
    const url = "https://example.com";
    const modifiedRequest = new Request(url, request);
    // ...
  },
};

Response

fetch() handlerの返り値(Response)

これも、Fetch APIResponseと同じ

Context(ctx)

fetch() handlerctx

@cloudflare/workders-typesの型定義をみるとこんな感じ
最初だと、ちょっとイメージがつきにくいけど、便利な処理ができる

interface ExecutionContext {
  // レスポンスを返した後でも、非同期で引数のタスクを実行してくれる
  waitUntil(promise: Promise<any>): void;
  // workersで処理をやめ、オリジンサーバにリクエストを渡す例外を投げる
  passThroughOnException(): void;
  props: any;
}

Fetch

Fetch APIはこのあたり

Cache

Cloudflareのキャッシュを読み書きできるAPI

オプションとかでいろいろ設定できるけど、ざっくりこんな感じで使える

const cache = caches.default

// キャッシュがあるかの判定
await cache.match(request);

// キャッシュの保存
await cache.put(request, response);

// キャッシュの削除
await cache.delete(request, options);

HTMLRewriter

HTMLをjQueryっぽい感じでリライトできるAPI

const res = await fetch(req);

new HTMLRewriter()
  .on('*', new ElementHandler())
  .onDocument(new DocumentHandler())
  .transform(response);

ハンドラーには、ElementHandlerDocumentHandlerの2つがあるよう

  • ElementHandler ... divなどのHTML要素やcommentstextに対して処理できる
  • DocumentHandler ... doctypeendを含めHTMLドキュメント全体に対して処理できる

その他もろもろ

GitHub Actionでの自動デプロイ

CD/CIについては、このあたりに書いてある

Webアプリ/Webサイト

まだBetaだけど、フロントエンドWebサイト向けで、
いくつかのフレームワークに対応してるらしい

静的ページ/静的アセット

まだBetaだけど、Cloudflare Pagesぽいことができるらしい

データベースへの接続

WorkersからDBにアクセスできるっぽい

対応言語

今のところ、JavaScript/TypeScript/Python/Rustっぽい
WebAssembly(Wasm)もサポートしてるっぽい


以上!なんとなく理解してきたぞ...(*´ω`*)

参考にしたサイト様