[Cloudflare Workers] とりあえず入門してみる

# Cloudflareとは
Webサイトへのさまざまな攻撃を防御しながら、同時にサイトの表示速度を大幅に改善できるCDN（Content Delivery Network）サービスのこと。 
2024年8月現在、Cloudflareは世界シェア1位を誇り、CDN市場の83.1％を占めている。

# これから入門するCloudflare Workersとは
Cloudflare Workersはサーバーレス実行環境を提供し、インフラストラクチャの設定や保守を行うことなく、新規アプリケーションの作成や既存アプリケーションの拡張が可能。

# とりあえず触ってみる
1. Cloudflare アカウントにサインアップする。
    - 以下リンクから行う。
    - https://dash.cloudflare.com/sign-up
2. サブドメインを設定する。
    - Cloudflareトップページ > Workers & Pagesから設定する。
    - 今回は「sample-worker」にする。
3. npmをインストールする。
    - 以下リンクを参考に行う。
    - https://docs.npmjs.com/getting-started
4. Node.jsをインストールする。
    - 以下リンクを参考に行う。
    - https://nodejs.org/en/
5. Workerプロジェクトを作成する。
    - 以下コマンドを実行する。
    ```
     npm create cloudflare@latest -- sampleWorker
    ```

    - いくつか質問がされるので以下のように回答していく。
    ```bash
    Ok to proceed? (y)
    #=> y

    In which directory do you want to create your application?
    # プロジェクト名を入力
    #=> sampleWorker
    
    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?
    # 今回はTypeScriptを選択する
    #=> lang TypeScript

    Do you want to deploy your application?
    #=> yes
    ```
6. 動作確認
    - 以下のコマンドを実行する。
    ```bash
    # XXXの部分はユーザーネームになります
    $ curl https://sample-worker.XXX.workers.dev
    Hello World!
    ```

    - ローカル環境で動作確認を行う場合は以下のコマンドを実行する。
    ```bash
    # コード変更後に確認したい場合は以下のコマンドを実行してから行う
    $ npx wrangler deploy

    # ローカル環境のWorkerを起動する
    $ npx wrangler dev

    # デフォルトでlocalhost:8787で接続可能
    $ curl http://localhost:8787
    Hello World!
    ```


## ちょっとだけ深掘りしていく
### 生成されたファイル
- ./src/index.ts にWorkerの設定ファイルが生成されている。
    - fetch関数は3つの引数を受け取って処理を行う。
        - request
            - クライアントからのHTTPリクエストを表す。
            - 参考： [Request - Web APIs - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Request)
        - env
            - 環境変数や設定を含むオブジェクト。
            - `./worker-configuration.d.ts`に型定義ファイルが存在するため、必要に応じて設定する。
            - 参考： [Environment variables](https://developers.cloudflare.com/workers/configuration/environment-variables/)
        - ctx
            - コンテキストオブジェクトで、リクエストに関連する追加情報が含める。
            - 参考： [Context(ctx)](https://developers.cloudflare.com/workers/runtime-apis/context/)
    - ResponseはJavaScript標準APIで定義されたインターフェースに準拠。
        - 参考： [Response - Web APIs - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Response)
    - satisfies ExportedHandler<Env>
        - `satisfies`はTypeScriptの構文で、オブジェクトが特定の型を満たしていることをコンパイル時に確認する。
        - fetch関数が`ExportedHandler`の型通り定義されていることを期待する。
        - プロジェクトの環境やライブラリによって異なるが一般的に以下のような型定義となる。
            ```index.d.ts
            type ExportedHandlerFetchHandler<Env = unknown, CfHostMetadata = unknown> = (
              request: Request<CfHostMetadata, IncomingRequestCfProperties<CfHostMetadata>>,
              env: Env,
              ctx: ExecutionContext,
            ) => Response | Promise<Response>;
            ```
    ```src/index.ts
    /**
     * Welcome to Cloudflare Workers! This is your first worker.
     *
     * - Run `npm run dev` in your terminal to start a development server
     * - Open a browser tab at http://localhost:8787/ to see your worker in action
     * - Run `npm run deploy` to publish your worker
     *
     * Bind resources to your worker in `wrangler.toml`. After adding bindings, a type definition for the
     * `Env` object can be regenerated with `npm run cf-typegen`.
     *
     * Learn more at https://developers.cloudflare.com/workers/
     */
    
    export default {
    	async fetch(request, env, ctx): Promise<Response> {
    		return new Response('Hello World!');
    	},
    } satisfies ExportedHandler<Env>;
    ```

### Wranglerについて
Cloudflare開発者プラットフォームのコマンドラインインターフェイス(CLI)である`Wrangler`を使用することで、Workerプロジェクトを管理できる。

#### サンプル設定ファイル

```wrangler.toml
# ワーカー名
name = "my-worker"

# メインのエントリーポイントファイル
main = "src/index.js"

# Cloudflare Workersのデフォルトのサブドメイン（workers.dev）で開発用として公開するかどうかを指定
workers_dev = false

# このWorkerが適用されるルートを指定
route = { pattern = "example.org/*", zone_name = "example.org" }

# Workers KVの名前空間を設定
# bindingはコード内で参照される名前で、idは実際のKV名前空間のID
kv_namespaces = [
  { binding = "<MY_NAMESPACE>", id = "<KV_ID>" }
]
```

#### 主なコマンド一覧
| コマンド                    | 説明                                                                 |
|-----------------------------|----------------------------------------------------------------------|
| `wrangler d1`                | D1 と対話します。                                                     |
| `wrangler deploy`            | Worker を Cloudflare にデプロイします。                               |
| `wrangler dev`               | ワーカーを開発するためのローカル サーバーを起動します。                |
| `wrangler delete`            | Cloudflare からワーカーを削除します。                                 |
| `wrangler kv namespace`      | Workers KV 名前空間を管理します。                                    |
| `wrangler kv key`            | Workers KV 名前空間内のキーと値のペアを管理します。                   |
| `wrangler kv bulk`           | Workers KV 名前空間内の複数のキーと値のペアをバッチで管理します。     |
| `wrangler r2 bucket`         | Workers R2 バケットを管理します。                                    |
| `wrangler r2 object`         | Workers R2 オブジェクトを管理します。                                |
| `wrangler secret`            | ワーカーの秘密変数を管理します。                                     |
| `wrangler secret:bulk`       | ワーカーの複数のシークレット変数を管理します。                       |
| `wrangler queues`            | ワーカー キューを構成します。                                         |
| `wrangler login`             | OAuth を使用して、Cloudflare アカウントで Wrangler を承認します。     |
| `wrangler logout`            | アカウントにアクセスするための Wrangler の承認を削除します。          |
| `wrangler deployments`       | 最近のデプロイメントの詳細を取得します。                              |
| `wrangler rollback`          | 最近のデプロイメントにロールバックします。                            |

# 参考
[Cloudflare Workers](https://developers.cloudflare.com/workers/)
[入門Cloudflare Workers](https://zenn.dev/moutend/articles/97c98a277f4bae)