deno deployで簡単なWeb APIを作る

deno deployを利用して簡単なWeb APIを作ってみようと思います。

どんなAPIがいいか迷ったのですが、文章を単語に分割してくれる[Intl.Segmenter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter)という関数を発見。

今回はこの`Intl.Segmenter`を使って、クエリパラメータで渡した文章を単語に分割し、JSONで返すAPIを作っていきましょう。

# Web APIのひな型

公式ドキュメントを参考に、クエリパラメータに応じてJSONを返却するコードを書くと、このようになります。

```ts
addEventListener("fetch", (event) => {
  // リクエストされたURLから結果データを作成
  const url = new URL(event.request.url)
  const result = /*urlを元に結果データを作成するコードをここに書く*/

  // 結果データをJSON化し、クライアントに返却
  event.respondWith(
    new Response(JSON.stringify(result), {
      status: 200,
      headers: {
        "content-type": "application/json",
      },
    }),
  );
});
```

後は4行目を穴埋めするだけです。

# 結果データを作成する処理を書く

まずURLからクエリパラメータを取り出します。`url.searchParams.get('パラメータ名')`でOKです。

```ts
/*
https://word-seg.deno.dev/?text=国境の長いトンネルを抜けると、そこは錦糸町だった。&lang=ja
-> targetText: "国境の長いトンネルを抜けると、そこは錦糸町だった。"
-> targetLang: "ja"
*/
const url = new URL(event.request.url)
const targetText = url.searchParams.get('text') ?? `吾輩は猫である。名前は${crypto.randomUUID()}`
const targetLang = url.searchParams.get('lang') ?? 'ja'
```

ついでにクエリパラメータが与えられなかった時の処理も書いておきましょう。ここでは、適当なデフォルト値にフォールバックさせることにしました。猫の名前は[`crypto.randomUUID()`](https://www.chromestatus.com/feature/5689159362543616)に決めてもらいます。

次に、取り出したクエリパラメータから結果データを作成する処理を書きます。

```ts
/*
吾輩は猫である。名前はたぬき。
-> result: ["吾輩", "は", "猫", "で", "ある", "。", "名前", "は", "たぬき", "。"]
*/
const segments = new Intl.Segmenter(targetLang, {granularity: "word"}).segment(targetText);
const result = [...segments].map(seg=>seg.segment)
```

以上で必要な処理は全て書き終わりました！続いて、deno deployからデプロイしていきましょう。

# deployする

### 1. githubへソースコードをpush

先ほど作成したソースコードを、githubへアップロードします。（詳しい手順は割愛）

```ts
addEventListener("fetch", (event) => {
  // リクエストされたURLから結果データを作成
  const url = new URL(event.request.url)
  const targetText = url.searchParams.get('text') ?? `吾輩は猫である。名前は${crypto.randomUUID()}`
  const targetLang = url.searchParams.get('lang') ?? 'ja'
  const segments = new Intl.Segmenter(targetLang, {granularity: "word"}).segment(targetText);
  const result = [...segments].map(seg=>seg.segment)

  // 結果データをJSON化し、クライアントに返却
  event.respondWith(
    new Response(JSON.stringify(result), {
      status: 200,
      headers: {
        "content-type": "application/json",
      },
    }),
  );
});
```

### 2. プロジェクトの作成

まず、 https://deno.com/deploy にアクセスし、アカウントを登録します。

次に、 https://dash.deno.com/new から新しいプロジェクトを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/4e49f454-a5cc-b7e6-9b92-0d466b414ffe.png)

ここで設定した名前が公開時に**ドメイン名の一部**に使われます。
例えば myapp という名前を使うと、 myapp.deno.dev というドメイン名になります。（自分で用意したドメインを使うことも可能）

### 3. コードの登録

次に、作成したコードを登録します。

コードの登録は

- github連携からデプロイ
- URLからデプロイ

の2種類のやり方があります。

今回はgithub連携を使用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/4ae245fd-c8f4-c2a7-d890-8349191a3993.png)

「Continue」を選択すると、githubのURLを聞いてくるので、先ほどpushしたリポジトリのURLを入力します。
ちなみに、他人のリポジトリでも大丈夫らしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/25042023-432a-05fd-cb58-25c1069b2b4e.png)


最後に「Link」をクリックするとデプロイ完了です。

簡単に出来ましたね。
作成したAPIはこちら↓で公開中です！

https://word-seg.deno.dev/

# コードを変更したい時はどうするか

普通にcommitしてpushすると更新されます。

プルリクエストを開くと、変更後のコードを利用したプレビュー用のデプロイが公開されます。
緑色のチェックマークをクリック→detailsをクリック　でプレビュー用のページに飛ぶことが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/678625/208e441a-4498-966f-e431-b85f079f547d.png)

# まとめ

記事中のコードにCORS対応を入れるの忘れました。