EdgeWorkers の API オーケストレーションのサンプルコードを Sandbox 上で動かす

Akamai EdgeWorkers のコードをローカル環境で確認するには Akamai Sandbox を使います。Akamai Sandbox を利用すると、ローカルマシン上で自分が書いたコードをすぐに検証できるので、開発効率が上がります。今回は前回の記事の続きとして、Sandbox を利用して、外部の API を呼び出すことができるかを確認します。また、前回紹介できなかった Akamai CDN の配信設定の例やサードパーティAPI の例なども記載します。

https://qiita.com/110hideki/items/5721297cd0a78b4f8c75

![EdgeComputing_sandbox.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/0a89b4ec-5036-e30a-8a2d-1a1a8a7c60a0.jpeg)


# 前提

EdgeWorkers が動作する Akamai の配信設定は ``www.foo.com`` とします。

Sandbox を動作するクライアントは MacOS です。

API オーケストレーションが動作するエンドポイントは ``https://www.foo.com/ew/api-orchestration`` とします。



# Sandbox を作成する

事前に Sandbox 環境をインストールする必要があります。
```
akamai install sandbox
```

下記の記事も参照ください。

https://qiita.com/110hideki/items/c559c1ea154280c80530

API オーケストレーションのコードを検証するための Sandbox 環境を作成します。Sandbox create の文法は次のようになります。

```shell
>> akamai sandbox create --help
Usage: akamai-sandbox create [options]

Creates a new sandbox.

Options:
  -r, --rules <file>                                    JSON file containing a PAPI rule tree. You need to specify a
                                                        property or hostname to base the sandbox on when using this
                                                        method.
  -p, --property <property-id | property-name:version>  Property to base the sandbox on. If an active version is not
                                                        found, the most recent version is used.
  -o, --hostname <hostname>                             The hostname of your Akamai property, such as
                                                        www.example.com.
  -c, --clonable <boolean>                              Make this sandbox clonable.
  -n, --name <string>                                   Name of the sandbox.
  -H, --requesthostnames <string>                       Comma separated list of request hostnames.
  --recipe <file>                                       Path to recipe.json file.
  -C, --cpcode <cpcode>                                 Specify an existing cpcode instead of letting the system
                                                        generate a new one.
  --origin-from <property | config>                     Redirect origin traffic to the origins defined in your Akamai
                                                        property or config file.
  -h, --help                                            Output usage information.
```

Akamai CDN の設定はバージョン管理されるので、、どのバージョンを基に Sandbox 環境を作成するかを明示的に ``-p`` の引数で指定すると良いです。例えば、次のように複数バージョンがあり、プロダクション、ステージングで有効となっているバージョンが異なり、また、最新のバージョンがアクティベーションされていない状況ではどのバージョンをベースとして Sandbox 環境が作るか混乱するときがありますので、バージョンを指定することをお勧めします。
![ion-config-version22.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/f58bbea4-728a-53c5-35a7-15de50aec1fb.jpeg)

以下の例は配信プロパティ名が ``www.foo.com`` でバージョン ``22`` をベースとして Sandbox 環境を作成することを意味します。新規に作成する Sandbox の名称は ``my-foo-sandbox`` です。
```
akamai sandbox create -p www.foo.com:22 -n my-foo-sandbox
```

以下は作成したときのログのサンプルです。``www.foo.com`` の配信設定の中では Origin サーバーが ``XXX-XXX-XXX-XXX.ip.linodeusercontent.com``、``my-json-server.typicode.com`` と設定されており、ログ上ではその Origin サーバーが検知されています。

```shell
>> akamai sandbox create -p www.foo.com -n my-foo-sandbox
building origin list
Detected the following origins: XXX-XXX-XXX-XXX.ip.linodeusercontent.com, my-json-server.typicode.com.
Do you want the Sandbox Client to proxy the origins in your dev environment to the destination defined in the Akamai
 config? Enter **y** and the CLI will automatically update your configuration file. If you want to route sandbox traff
ic to different development origins, enter **n** to customize the origin mappings. (Y/n)
```
``Y`` を選択すると、Sandbox 環境が作成されます。
```
registering sandbox in local datastore
sandbox-id: df1dde58-6ea2-4caf-9968-XXXXXXXXXXXX my-foo-sandbox is now active
Successfully created sandbox-id df1dde58-6ea2-4caf-9968-XXXXXXXXXXXX Generated sandbox client configuration at /Users/ito/.akamai-cli/cache/sandbox-cli/sandboxes/my-foo-sandbox/config.json Edit this file to specify the port and host for your dev environment.
```


## Sandbox 環境を確認

```
akamai sandbox list
```
下記の例では Sandbox 環境が一つしかないですが、複数作成することもできます。デフォルトの Sandbox は ``YES`` と表示されます。
```shell
>> akamai sandbox list
Local sandboxes:

Default  Sandbox Name                    Sandbox ID                            JWT Expiration Date
-------  ------------------------------  ------------------------------------  -------------------------- 
YES      my-foo-sandbox                  df1dde58-6ea2-4caf-9968-XXXXXXXXXXXX  Oct 27, 2023, 10:48 AM UTC
```

# Sandbox を起動する

```
akamai sandbox start
```

出力のサンプルです。端末を２つ立ち上げ、一つの端末では Sandbox の標準出力を常に表示すると良いと思います。

```shell
>> akamai sandbox start
Starting Sandbox Client with arguments:
Config: /Users/ito/.akamai-cli/cache/sandbox-cli/sandboxes/my-foo-sandbox/config.json
Logging path: /Users/ito/.akamai-cli/cache/sandbox-cli/sandboxes/my-foo-sandbox/logs
Logging file: /Users/ito/.akamai-cli/cache/sandbox-cli/sandboxes/my-foo-sandbox/logs/sandbox-client.log
Logging config: /Users/ito/.akamai-cli/cache/sandbox-cli/sandbox-client-1.4.0-RELEASE/conf/logback.xml

Arguments: "/usr/bin/java",-DLOG_PATH="/Users/ito/.akamai-cli/cache/sandbox-cli/sandboxes/my-foo-sandbox/logs",-DLOGGING_CONFIG_FILE="/Users/ito/.akamai-cli/cache/sandbox-cli/sandbox-client-1.4.0-RELEASE/conf/logback.xml",-jar "/Users/ito/.akamai-cli/cache/sandbox-cli/sandbox-client-1.4.0-RELEASE/lib/sandbox-client-1.4.0-RELEASE.jar",--config="/Users/ito/.akamai-cli/cache/sandbox-cli/sandboxes/my-foo-sandbox/config.json"

Successfully launched Akamai Sandbox Client
Sandbox Client running on port: 9550
```

## Sandbox 経由で API オーケストレーションが動作するかを確認

すでに ``http://www.foo.com/ew/api-orchestration``の URL で API オーケストレーションのサンプルコードが動作している必要があります。Sandbox はローカルホストの ``9550`` ポートを使っていますので、``127.0.0.1:9550`` をホスト名として curl でリクエストを送信します。

```shell
>> curl -i http://127.0.0.1:9550/ew/api-orchestration -H 'Host: www.foo.com' 
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=0
Date: Sun, 30 Apr 2023 11:02:46 GMT
Content-Length: 1670
Connection: keep-alive
X-Akamai-Sandbox: true
X-Akamai-Staging: ESSL

{"endPoint1":{"songs":[{"id":1,"name":"Thriller","artists":[1],"lylics":1},{"id":2,"name":"Billie Jean","artists":[1],"lylics":2},{"id":3,"name":"Beat It","artists":[1],"lylics":3},{"id":4,"name":"We Are The World","artists":[1],"lylics":4},{"id":5,"name":"Bad","artists":[1],"lylics":5},{"id":6,"name":"Man In The Mirror","artists":[1],"lylics":6},{"id":7,"name":"Dirty Diana","artists":[1],"lylics":7},{"id":8,"name":"Black or White","artists":[1],"lylics":8},{"id":9,"name":"I Want You Back","artists":[2],"lylics":9},{"id":10,"name":"ABC","artists":[2],"lylics":10},{"id":11,"name":"The Love You Save","artists":[2],"lylics":11}],"artists":[{"id":1,"name":"Michael Jackson","song":[1,2,3,4,5,6,7,8]},{"id":2,"name":"Jackson 5","songs":[9,10]}],"lylics":[{"id":1,"name":"https://genius.com/albums/Michael-jackson/Thriller","songs":[1]},{"id":2,"name":"https://genius.com/Michael-Jackson-billie-jean-lyrics","songs":[2]},{"id":3,"name":"https://genius.com/Michael-Jackson-beat-it-lyrics","songs":[3]},{"id":4,"name":"https://genius.com/Usa-for-africa-we-are-the-world-lyrics","songs":[4]},{"id":5,"name":"https://genius.com/Michael-Jackson-bad-lyrics","songs":[5]},{"id":6,"name":"https://genius.com/Michael-Jackson-man-in-the-mirror-lyrics","songs":[6]},{"id":7,"name":"https://genius.com/Michael-jackson-dirty-diana-lyrics","songs":[7]},{"id":8,"name":"https://genius.com/Michael-jackson-black-or-white-lyrics","songs":[8]},{"id":9,"name":"https://genius.com/Jackson-5-i-want-you-back-lyrics","songs":[9]},{"id":10,"name":"https://genius.com/Jackson-5-abc-lyrics","songs":[10]},{"id":11,"name":"https://genius.com/Jackson-5-the-love-you-save-lyrics","songs":[11]}]}}
```
ローカルの 9550 ポートを通して、外部の API サーバから取得したデータを端末に表示することができています。このように Sandbox 環境を利用して外部の API サーバーからの応答を簡単に確認できます。

もし、まだ Akamai ネットワーク上に API オーケストレーションのコードをアクティベーションしていない場合は、後述する [Sandbox にバンドルファイルを登録] を確認してください。

## 現在の EdgeWorkers の API オーケストレーションコードの確認

EdgeWorkers のコードでは以下のパスを呼び出しています。
```javascript
const endPoint1 = '/110hideki/mockapi/db';
// const endPoint2 = '/api/example/endpoint2';
// const endPoint3 = '/api/example/endpoint3';
```
配信設定が ``www.foo.com`` であれば、``https://www.foo.com/110hideki/mockapi/db`` を呼び出しています。また、Akamai CDN の``www.foo.com`` の配信設定では、``/110hideki/`` のパスのオリジンサーバーは ``my-json-server.typicode.com/``としています。つまり、上記の EdgeWorkers のコードは間接的に、``https://my-json-server.typicode.com/110hideki/mockapi/db`` を呼び出していることになります。



# EdgeWorkers のコードをダウンロードする
EdgeWorkers CLI を使うと、Akamai に登録されている EdgeWorkers のコードをダウンロードすることもできます。

```shell
>> akamai ew download --help
Usage: akamai-edgeworkers download|download-version [options] <edgeworker-identifier> <version-identifier>
```

``help`` では、``EdgeWorkers ID`` と ``バージョン`` が必要なことが分かります。次の例では、 EdgeWorkers ID ``43797`` の バージョン ``0.1`` をダウンロードします。

```shell
>> akamai ew download 43797 0.1
Saving downloaded bundle file at: /Users/ito/.akamai-cli/cache/edgeworkers-cli/edgeworkers/43797
INFO: File saved @ /Users/ito/.akamai-cli/cache/edgeworkers-cli/edgeworkers/43797/ew_0.1_1682853042908.tgz
```
## バンドルファイルの中身を確認

ダウンロードした ``ew_0.1_1682853042908.tgz`` は EdgeWorkers のバンドルファイルです。解凍すると ``main.js`` と ``bundle.json`` が見えます。

```shell
>> tar xvf ew_0.1_1682853042908.tgz
x main.js
x bundle.json
```
## main.js
```javascript
/*
(c) Copyright 2020 Akamai Technologies, Inc. Licensed under Apache 2 license.

Version: 0.1
Purpose:  Combine 3 api endpoints returning JSON into a single JSON response.

*/

import { httpRequest } from 'http-request';
import { createResponse } from 'create-response';

const endPoint1 = '/110hideki/mockapi/db';
// const endPoint2 = '/api/example/endpoint2';
// const endPoint3 = '/api/example/endpoint3';

async function getJSON (url) {
  const response = await httpRequest(`${url}`);
  if (response.ok) {
    return await response.json();
  } else {
    return { error: `Failed to return ${url}` };
  }
}

// The responseProvide function generates a response, acting as a "surrogate origin".
// The response may be cached according to the caching rules configured in the property.
export async function responseProvider (request) {
  const result = {};

  // Make all requests in parallel to retrieve content.
  const endPointResult1 = getJSON(endPoint1).then(json => { result.endPoint1 = json; });
  // const endPointResult2 = getJSON(endPoint2).then(json => { result.endPoint2 = json; });
  // const endPointResult3 = getJSON(endPoint3).then(json => { result.endPoint3 = json; });

  // Wait for all requests to complete.
  // await Promise.all([endPointResult1, endPointResult2, endPointResult3]);
  await Promise.all([endPointResult1]);

  // Return merged JSON as the response.
  return Promise.resolve(createResponse(
    200,
    { 'Content-Type': ['application/json'] },
    JSON.stringify(result)
  ));
}
```

## bundle.json
```
{
    "edgeworker-version": "0.1",
    "description" : "Simple API Orchestration Response - Buffered Response Version"
}
```

# EdgeWorkers のコードを変更する

現在は一つの API エンドポイントを使っているので、EdgeWorkers から２つ以上の API エンドポイントを呼び出すように変更します。
| 呼び出し番号 | エンドポイントの URL |
|:-:|:-:|
| 1  | https://www.foo.com/110hideki/mockapi/songs/1  |
| 2  | https://www.foo.com/110hideki/mockapi/songs/2  |

最終的には次のような構成となります。
![EdgeComputing_patterns-sandbox.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/d68cfeac-0547-069d-febc-95dad55b367e.jpeg)



## main.js の変更

```javascript
const endPoint1 = '/110hideki/mockapi/songs/1';
const endPoint2 = '/110hideki/mockapi/songs/2';
// const endPoint3 = '/api/example/endpoint3';
```

```javascript
 // Make all requests in parallel to retrieve content.
  const endPointResult1 = getJSON(endPoint1).then(json => { result.endPoint1 = json; });
  const endPointResult2 = getJSON(endPoint2).then(json => { result.endPoint2 = json; });
//  const endPointResult3 = getJSON(endPoint3).then(json => { result.endPoint3 = json; });
```

```javascript
// await Promise.all([endPointResult1, endPointResult2, endPointResult3]);
await Promise.all([endPointResult1, endPointResult2]);
```

## bundle.json の変更
バンドルファイルのバージョンを ``0.1`` から ``0.2`` に変更します。
```shell
>> cat bundle.json
{
    "edgeworker-version": "0.2",
    "description" : "Simple API Orchestration Response - Buffered Response Version"
}
```

## バンドルファイルの作成

```
tar cvzf ew-bundle.tgz main.js bundle.json 
```

## Sandbox にバンドルファイルを登録
Sandbox に登録するときも EdgeWorkers ID は必須です。この例では ``43797`` です。
```shell
>> akamai sandbox add-edgeworker 43797 ew-bundle.tgz
done!
```

## EdgeWorkers ID の確認
EdgeWorkers ID は常に重要な概念です。Akamai Control Center でも確認できますし、EdgeWorkers CLI でも確認できます。以下は EdgeWorkers CLI で確認したときの例です。分かりやすい名前をつけて、管理を容易にしてください。
```shell
>> akamai ew list-ids
------------------------------------------------------------------------------------------------------------
--- The following EdgeWorker Ids are currently registered for account: V-V-VVVVVV, group: any, ewId: any ---
------------------------------------------------------------------------------------------------------------
edgeWorkerId  name                       groupId  resourceTierId
------------  -------------------------  -------  --------------          
43796         hiito-hello-world          XXXXXX   200           
43797         hiito-api-orchestration    XXXXXX   200              
```

## Sandbox 環境のテスト
EdgeWorkers CLI で登録したコードはすぐにローカル環境で確認できます。以下の例では新しい API エンドポイントから得られた情報が表示されています。
```shell
>> curl http://127.0.0.1:9550/ew/api-orchestration -H 'Host: www.foo.com' 
{
"endPoint1":{"id":1,"name":"Thriller","artists":[1],"lylics":1},
"endPoint2":{"id":2,"name":"Billie Jean","artists":[1],"lylics":2}
}
```

# Akamai Network に EdgeWorkers を登録する
Sandbox 環境で動作確認した後は、Akamai Network 上に EdgeWorkers を登録します。EdgeWorkers upload コマンドを使います。
```
akamai ew upload --help
```

登録したときの出力サンプルです。
```shell
>> akamai ew upload 43797 --bundle 43797-ew-bundle.tgz
-----------------------------------------------------
--- New version uploaded for EdgeWorker Id: 43797 ---
-----------------------------------------------------
edgeWorkerId  version  checksum                                                          createdBy   createdTime         
------------  -------  ----------------------------------------------------------------  ----------  --------------------
43797         0.2      879ff3e4d2fda62b4bbe2e6d86310d4731f34edf630fa7ef72f755461a72aa64  computesme  2023-05-01T10:43:27Z
```

### EdgeWorkers の登録状況の確認
```shell
>> akamai ew status 43797
----------------------------------------------------------------------------------------------------------------------------------
--- The following EdgeWorker Activations currently exist for account: V-V-VVVVVV, ewId: 43797, version: any, activationId: any ---
----------------------------------------------------------------------------------------------------------------------------------
edgeWorkerId  version  activationId  status    network  createdBy   createdTime         
------------  -------  ------------  --------  -------  ----------  --------------------
43797         0.1      1             COMPLETE  STAGING  computesme  2023-05-01T09:19:00Z
```

## EdgeWorkers ID のアクティベート

``akamai ew activate``コマンドを使います。
```shell
>> akamai ew activate --help
Usage: akamai-edgeworkers activate|av [options] <edgeworker-identifier> <network> <version-identifier>

Activate a Version for a given EdgeWorker Id on an Akamai Network

Options:
  -h, --help  display help for command

Copyright (c) 2019-2021 Akamai Technologies, Inc. Licensed under Apache 2 license.
Your use of Akamai's products and services is subject to the terms and provisions outlined in Akamai's legal policies.
Visit http://github.com/akamai/cli-edgeworkers for detailed documentation
```

activate コマンドを実行したときの出力サンプルです。
```shell
>> akamai ew activate 43797 STAGING 0.2
-------------------------------------------------------------------------------------------------
--- New Activation record created for EdgeWorker Id: 43797, version: 0.2, on network: STAGING ---
-------------------------------------------------------------------------------------------------
edgeWorkerId  version  activationId  status     network  createdBy   createdTime         
------------  -------  ------------  ---------  -------  ----------  --------------------
43797         0.2      2             PRESUBMIT  STAGING  computesme  2023-05-01T10:50:26Z
```

### ステータスの再確認
ステージングのアクティベーションには 2 分ほど時間がかかります。activate コマンドの起動直後は ``PRESUBMIT`` のステータスとなっています。
```shell
>> akamai ew status 43797
----------------------------------------------------------------------------------------------------------------------------------
--- The following EdgeWorker Activations currently exist for account: V-V-VVVVVV, ewId: 43797, version: any, activationId: any ---
----------------------------------------------------------------------------------------------------------------------------------
edgeWorkerId  version  activationId  status     network  createdBy   createdTime         
------------  -------  ------------  ---------  -------  ----------  --------------------
43797         0.2      2             PRESUBMIT  STAGING  computesme  2023-05-01T10:50:26Z
43797         0.1      1             COMPLETE   STAGING  computesme  2023-04-08T09:19:00Z
```

二分ほど待つとステージング上に展開済 (``COMPLETE``)となります。

```shell
> akamai ew status 43797
----------------------------------------------------------------------------------------------------------------------------------
--- The following EdgeWorker Activations currently exist for account: V-V-VVVVVV, ewId: 43797, version: any, activationId: any ---
----------------------------------------------------------------------------------------------------------------------------------
edgeWorkerId  version  activationId  status    network  createdBy   createdTime         
------------  -------  ------------  --------  -------  ----------  --------------------
43797         0.2      2             COMPLETE  STAGING  computesme  2023-05-01T10:50:26Z
43797         0.1      1             COMPLETE  STAGING  computesme  2023-04-08T09:19:00Z
```

## ステージング環境のテスト
``/etc/hosts`` にステージングの IP アドレスを登録してから確認します。

```shell
>> curl https://www.foo.com/ew/api-orchestration
{
"endPoint1":{"id":1,"name":"Thriller","artists":[1],"lylics":1},
"endPoint2":{"id":2,"name":"Billie Jean","artists":[1],"lylics":2}
}
```

## プロダクション環境のアクティベート

```shell
>> akamai ew activate 43797 production 0.2
----------------------------------------------------------------------------------------------------
--- New Activation record created for EdgeWorker Id: 43797, version: 0.2, on network: PRODUCTION ---
----------------------------------------------------------------------------------------------------
edgeWorkerId  version  activationId  status     network     createdBy   createdTime         
------------  -------  ------------  ---------  ----------  ----------  --------------------
43797         0.2      3             PRESUBMIT  PRODUCTION  computesme  2023-05-01T10:59:54Z
```

### ステータスの再確認

```shell
>> akamai ew status 43797
----------------------------------------------------------------------------------------------------------------------------------
--- The following EdgeWorker Activations currently exist for account: V-V-VVVVVV, ewId: 43797, version: any, activationId: any ---
----------------------------------------------------------------------------------------------------------------------------------
edgeWorkerId  version  activationId  status    network     createdBy   createdTime         
------------  -------  ------------  --------  ----------  ----------  --------------------
43797         0.2      3             COMPLETE  PRODUCTION  computesme  2023-05-01T10:59:54Z
43797         0.2      2             COMPLETE  STAGING     computesme  2023-05-01T10:50:26Z
43797         0.1      1             COMPLETE  STAGING     computesme  2023-04-08T09:19:00Z
```


# 用意した API エンドポイント
## Akamai CDN から呼ばれる API エンドポイント
今回、https://my-json-server.typicode.com/ を活用しました。

https://my-json-server.typicode.com/110hideki/mockapi/

```
 curl https://my-json-server.typicode.com/110hideki/mockapi/songs/1
{
  "id": 1,
  "name": "Thriller",
  "artists": [
    1
  ],
  "lylics": 1
}
```

```
>> curl https://my-json-server.typicode.com/110hideki/mockapi/songs/2
{
  "id": 2,
  "name": "Billie Jean",
  "artists": [
    1
  ],
  "lylics": 2
}
```
## EdgeWorkers から呼ばれる API エンドポイント
``www.foo.com`` は皆さんの設定に合わせたドメイン名としてください。
```
% curl https://www.foo.com/110hideki/mockapi/songs/1
{
  "id": 1,
  "name": "Thriller",
  "artists": [
    1
  ],
  "lylics": 1
}
```

```
% curl https://www.foo.com/110hideki/mockapi/songs/2
{
  "id": 2,
  "name": "Billie Jean",
  "artists": [
    1
  ],
  "lylics": 2
}
```

# Akamai CDN の設定
## EdgeWorkers ID の設定
``/ew/api-orchestration`` に EdgeWorkers ID ``43797`` を割り当てています。
![ion-path-match-ew.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/cf00c4f0-6ce5-67d1-57ef-20e08d2c5609.jpeg)


![ion-patch-match-ew-behavior-43797.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/8cd051d0-a3af-ea5a-0276-837a0932f4f2.jpeg)

## Mock API の呼び出し設定
EdgeWorkers のコードから呼び出す API エンドポイントは Akamai で配信される必要があります。通常は ``api.foo.com`` などの別ホストであることが多いですが、今回は簡易的に一つの配信設定 ``www.foo.com`` でサードパーティのドメインを呼び出す例となっています。
![ion-config.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/69df3079-a7a3-8b3b-2c85-b9a574d0bd52.jpeg)

![ion-config-behavior-highlight.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264188/30824519-2f18-405e-4252-be147612da5e.jpeg)


# まとめ
Akamai EdgeWorkers は Akamai CDN 上で動作するため、Akamai CDN に関する前提知識が多少必要になってきます。本記事では、Akamai CDN を利用したことのない開発者の方が Akamai Sandbox を利用してローカルでコードを確認できるためにいくつかの例を示しています。Sandbox は EdgeWorkers だけでなく EdgeKV にも対応していますので、是非ご活用ください。