CloudflareのDurable Objectsをかる〜くご紹介

# オープニング
もういくつ寝るとクリスマスになりますね :santa:
エイチームフィナジーアドベントカレンダー15日目は @yothio が担当します。僕は普段サービスの開発・保守などを行っています、今回はサービスで活用している**Cloudflare**、その中の最近一般公開された**Durable Objects**についてお話しできればなと思います。

## 目次
- オープニング(さっきの挨拶部分)
- Cloudflareについてざっくりと
- Durable Objectsについて
- エンディング

## Cloudflareって？
Cloudflareについてご存知でしょうか？
CDNとして活用するのが個人的には比較的多いのかと考えますが、改めて見てみましょう

> Cloudflareは、インターネット上で運営されている最大のネットワークの1つです。
> ユーザーは、Webサイトやサービスのセキュリティとパフォーマンスを向上させる目的でCloudflareサービスを利用しています。


なるほど、つまりこういうことですね

- 最大のネットワークの1つである
- 使用することでセキュリティやパフォーマンスを向上できる

「最大のネットワーク」であることはCloudflareにかかわらず理解できると思うので
「どのように**セキュリティ**や**パフォーマンス**を向上させているのか」についてもう少し見ていきましょう

### CDN(Content Delivery Network)
Cloudflareには一般的にCDNというネットワークが構築されており、Cloudflare経由でコンテンツ(画像、スタイルシートなど)を配信する際にリクエストを送信するクライアントと地理的に近いCloudflareのサーバーからコンテンツを返却する事ができます。

具体的な例としては、AWSのマシンを使用してWebサービスを展開していたとしましょう。
そのWebサーバーはアメリカのオレゴン(us-west-2)に配置しており、そのサービスにアップロードされた画像なども同様にオレゴンリージョンのS3バケットに保存することとします。

私は大阪に居る状態でそのWebサービスへアクセスした場合
下記のようにサーバからのHTMLを受け取った後、HTMLにS3バケットのURLがimgタグに記載されていた場合、画像のダウンロードが実行され、ページが完全に表示されるまでに時間がかかるのは容易に想像できるかと思います。

```
大阪 <---> EC2(オレゴン)
大阪 <---> 画像(オレゴン)
```

では、仮にCloudflareを使用していた場合はどうなるでしょうか

```
大阪 <---> EC2(オレゴン)
大阪 <---> CDNエッジサーバー(大阪) <---> 画像(オレゴン)
```

サーバからのHTMLを受け取るところまでは先ほどと同じですが、画像のダウンロードの箇所についてはCDNエッジサーバーが大阪にてキャッシュを保持しており、オレゴンまで画像を取得する必要はありません。
このようにCDN上でコンテンツをキャッシュさせることによってWebサイトのパフォーマンスに寄与します。


## Durable Objectsについて
脱線しすぎましたね...
それでは本題のDurable Objectsについて見ていきましょう

Durable Objectsは昨年(2020年)に[ベータ版](https://blog.cloudflare.com/ja-jp/introducing-workers-durable-objects-ja-jp/)が公開され、先月[一般公開](https://blog.cloudflare.com/ja-jp/durable-objects-ga-ja-jp/)されました

Durable Objectsの特性としては

> グローバルな一意性とトランザクションストレージAPIの2つの機能を通じて
> ワーカープラットフォームに低レイテンシの調整と一貫したストレージを提供します。


1つずつ読み解いていきましょう。
まずDurable Objectsについて理解を深める上でとても大事なのが「`ワーカープラットフォーム`」という箇所ですね


### ワーカープラットフォーム

Cloudflare にはバックエンドのサーバーを用意せずにエッジネットワーク上で処理を実行できるサーバーレスの`Cloudflare Workers`があります。
今回Durable Objectsが指しているワーカープラットフォームというのもこちらのCloudflare Workersのことになります。

また、Cloudflare Workers以外にもフロントエンドアプリケーションをデプロイできるCloudflare Pagesが存在し、そちらでもDurable Objectsが使用できます

https://blog.cloudflare.com/building-full-stack-with-pages/


また、他のサーバーレスだとAWS LambdaやGoogle Cloud Functions などがありますね

### 低レイテンシの調整と一貫したストレージ

低レイテンシーということは、遅延が少なく
一貫したストレージということは、データ変更前後で整合性が取れているということでしょう

また一般公開時のブログに載っているように、Socketを使うことでリアルタイム性のあるチャットやホワイトボードなど様々なことが実現可能になりますね

## 実際に触ってみましょう
CloudflareがDurable Objectsについていくつかサンプルのコード・テンプレートなどがあるのでそちらを使用してデプロイして動作させるところまでやってみましょう

### 手順

1. リポジトリのクローン
2. wranglerのインストールとセットアップ
3. Workersのプランを有料に変更
4. デプロイコマンド実行

#### リポジトリのクローン
今回はこちらのシンプルなカウンターだけのテンプレートを使用します

https://github.com/cloudflare/durable-objects-template

```bash
$ git clone git@github.com:cloudflare/durable-objects-template.git
$ cd durable-objects-template
```

#### wranglerのインストールとセットアップ
cliでCloudflare Workersにデプロイするためにwranglerをインストールします
wranglerのREADEMEに書いてある通りコマンドを実行します

https://github.com/cloudflare/wrangler

その後、loginコマンドを実行してCloudflareのアカウントと紐付けます

```bash
$ npm i @cloudflare/wrangler -g

$ 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/oauth2/auth?XXXXXXX
✨  Successfully configured. You can find your configuration file at: /Users/[USERNAME]/.wrangler/config/default.toml
```

実際にログインコマンドを実行するとブラウザで認証が行われ
許可をした後に再度terminalに戻ると`Successfully`という文字とともにtokenなどが記載されたdefault.tomlが作成されます

↓Wranglerでログイン時のブラウザ認証

![スクリーンショット 2021-12-14 23.13.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/4ae26cff-689b-fc2b-3a38-afdb004202c3.png)


#### Workersのプランを有料に変更
CloudflareのダッシュボードのWorkers -> プランを選択して、無料プランになっている箇所を有料に変更します。
これはDurable Objectsを使用できるのはWorkersのプランが有料の場合のみのためです。

無料だと使用することはできませんが、Cloudflare Workers自体は使用できます。

※ こちらに貼ってある画面と現在は異なる恐れがあります

![スクリーンショット 2021-12-14 23.21.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/ae604a8f-45a0-9d7d-8556-5bb33541de2b.png)


#### デプロイコマンド実行
準備は整ったので後はデプロイするだけ、初回のDurable Objects使用時にはブラウザの方で確認されるはずです

```bash
$ wrangler publish
```

デプロイ後、Cloudflareのダッシュボードから該当のWorkers -> ルートを選択して実際ブラウザからアクセスしてみましょう

![スクリーンショット 2021-12-14 23.32.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/199819/9519f106-163a-33ab-4362-fbcbfee5b72b.png)


今回デプロイしたサンプルは簡易なカウンターでワーカーのルートに対して`/increment`,`/decrement`で値を増減できるものになります



### 余談
元々はプライベートでチャットを作成したいなと思っていたところ、Cloudflare のDurable ObjectsがGAされたことを聞いたことがきっかけでした
しかし、プライベートでチャットを使用する期日までにクレジットカードの承認が通らず、有料プランに切り替えれず、チャットを利用することを断念しました...悲しいね。 :cry: 


また、今回はシンプルなテンプレートを使用しましたが
他にはRollupやWebpackを使用したテンプレートやチャットのデモなどがありますのでぜひ触ってみてください 

https://github.com/cloudflare/durable-objects-rollup-esm

https://github.com/cloudflare/durable-objects-webpack-commonjs

https://github.com/cloudflare/workers-chat-demo


# エンディング
少し口下手なところもあったかと思いますが、Cloudflare、Durable Objectsについて少しでも知っていただければ嬉しく思います。

また、今回紹介したDurable Objects以外にも

- KVストアとして使える**Cloudflare KV**
- ページのデプロイホスティングなどを行える**Cloudflare Pages**
- 同一IPからの短時間アクセスを検知してブロックなどを行う**RateLimit**

などCloudflareではセキュリティやパフォーマンス、ソリューションのためツールをいくつも提供しているので
ぜひ使ってみてください（Freeプランもあるよ）

最後まで読んでくれてありがとうございました :santa:


# 参考元

- https://developers.cloudflare.com/fundamentals/get-started/cdn
- https://developers.cloudflare.com/workers/learning/using-durable-objects
- https://www.cloudflare.com/ja-jp/learning/what-is-cloudflare/