🦕

Deno Deployでコードをサクッと実行してURL APIも試す

2021/07/04に公開

Deno公式のエッジサーバーサービス、Deno Deployを使ってみました。

https://deno.com/deploy

Denoの象徴、夜の雨が降りしきるTOPページです。かっこいいですね。

ローカルで動かす

Deno Deployでは、ローカルサーバーを動かすdeployctlが提供されています。
https://deno.com/deploy/docs/running-scripts-locally
以下のコードで導入できます。

deno install --allow-read --allow-write --allow-env --allow-net --allow-run --no-check -f https://deno.land/x/deploy/deployctl.ts

公式のHello Worldを参考に、簡単なserver.tsを作成してみます。

https://deno.com/deploy/docs/hello-world

server.ts
addEventListener("fetch", (event) => {
  const response = new Response("Hello Deno Deploy!", {
    headers: { "content-type": "text/plain" },
  });
  event.respondWith(response);
});

実行! [1]

❯ deployctl run --watch ./server.ts
Check file:///Users/kawarimidoll/ghq/github.com/kawarimidoll/deno-deploy-practice/$deno$eval.ts
Check data:application/typescript;base64,(略)
Listening on http://0.0.0.0:8080

別ターミナルから確認してみます。

❯ curl 0.0.0.0:8080
Hello Deno Deploy!

疎通できています。
サクッとローカルサーバーを立てられました。

Deployする

ユーザー登録する

Deno Deployページ内のSign inかSign upを押すと登録画面へ遷移します。

GitHub連携で登録します。他の登録方法はないようです。

空っぽのダッシュボードに遷移します。
https://dash.deno.com/projects

これで登録は完了です。

リポジトリを連携する

GitHub連携でDeployするため、リポジトリを作成しました。
https://github.com/kawarimidoll/deno-deploy-practice

ではDeployします。
ダッシュボードのNew Projectからエントリーしましょう。

プロジェクト名の設定画面に入ります。
今回は練習なのでランダム生成の名前をそのまま使います。

続いてデプロイするコードの選択画面です。
提示されているサンプルもデプロイできるほか、Deploy URLを使うと、GitHubに限らず任意のサーバー上に公開されているコードを使ってDeployできます。
今回はとりあえずGitHub連携を使うので、下のDeploy from GitHubのContinueを選択します。

Deploy from GitHub
Publish a project from an existing GitHub repository.
Link this project to a GitHub repository to automatically deploy on push. Pushing to the default branch (usually main) will create a production deployment. Pushing to any other branch will create a preview deployment.

訳:

Deploy from GitHub
既存のGitHubリポジトリからプロジェクトを公開します。
プロジェクトをGitHubリポジトリにリンクすると、プッシュされたときに自動でデプロイされます。デフォルトブランチ(通常はmain)にプッシュした場合はProductionデプロイ、その他のブランチにプッシュした場合はPreviewデプロイとなります。

Continueするとリポジトリとの連携の画面に遷移します。

説明に従い、entrypointのファイルのGitHub URLを入力します。
今回はこちらです:https://github.com/kawarimidoll/deno-deploy-practice/blob/main/server.ts

入力するとProductionブランチの選択が表示されます。

デフォルトブランチを使うか、入力したブランチ(main)を使うかを選択します。
今回はどちらでも同じですが、リリース用としてデフォルト以外にreleaseとかpublishとかのブランチを用意する場合に使えそうです。

ということでLink、しようとしたらエラーが出ました。

連携するリポジトリにはDeno Deploy GitHub Appを導入する必要があります。
Install GitHub AppからDeno Deploy GitHub Appを導入しましょう。

All repositoriesで全リポジトリに反映させるか、Only select repositoriesでリポジトリを選択するかしてInstallします。
途中でGitHubの再サインインがあるかもしれません。

なお、既にDeno Deploy GitHub Appがユーザーに導入されている場合は、おちらの設定画面に飛ばされます。
同様にリポジトリとの連携設定を行ってください。

連携が成功するとDeno deployに戻ってきます。

リンクされました。

Back to projectでプロジェクトのトップに戻りましょう。

エンドポイントは[project-name].deno.devです。
ページ右上のVisitがリンクになっているので、ここからアクセスしてみます。

OKですね。作成したコードがWeb上でも動作しています。

パスに応じた処理を行う

これだけだとアクセスに対しHelloを返すだけですね。
少し実際のアプリケーションに近づけるため、かなりローレベルですが、URL APIを使って処理を追加してみます。

https://developer.mozilla.org/ja/docs/Web/API/URL/URL

server.ts
  addEventListener("fetch", (event) => {
+   const { host, pathname, searchParams } = new URL(event.request.url);
+   const params = Object.fromEntries([...searchParams.entries()]);

+   console.log({ host, pathname, params });

+   const message = "Hello Deno Deploy!";

+   if (pathname.endsWith(".json")) {
+     const response = new Response(JSON.stringify({ message, params }), {
+       headers: { "content-type": "application/json" },
+     });
+     event.respondWith(response);
+     return;
+   }

-   const response = new Response("Hello Deno Deploy!", {
+   const response = new Response(message + " from " + pathname, {
      headers: { "content-type": "text/plain" },
    });
    event.respondWith(response);
  });

ローカル実行用のdeployctlコマンドにwatchオプションを付けていれば、server.tsを更新すると自動でサーバーが再起動します。

これでリクエストしてみます。

❯ curl '0.0.0.0:8080'
Hello Deno Deploy! from /

❯ curl '0.0.0.0:8080/test'
Hello Deno Deploy! from /test

❯ curl '0.0.0.0:8080/test.json'
{"message":"Hello Deno Deploy!","params":{}}

❯ curl '0.0.0.0:8080/test.json?q=deno&lang=ja'
{"message":"Hello Deno Deploy!","params":{"q":"deno","lang":"ja"}}

pathnamesearchParamsを認識できています。

ではmainブランチにpushします。
ダッシュボードを確認すると、即座に反映されていることがわかります。

以下の通り、Web上での実行も問題ありません。

URLを扱う処理を確認できました。
もちろん、大きいアプリケーションを作る場合は、フレームワークを使うべきだとは思いますが、このくらいなら純粋なDenoのコードでもできてしまうというのがすごいところです。

ログを見る

プロジェクトトップにLogsというリンクがあります。

ページに移動すると、console.log()された内容を確認できます。

Show timestampsやShow log levelsにチェックを入れれば、時刻やログレベルの確認も可能です。
timestampは日本時間で出るようです。

Log levelまで見られるのは便利です。
これなら以下の記事で自作したようなログ機能も要りませんね。
https://zenn.dev/kawarimidoll/articles/b1d9bc15aaa99c

おわりに

以上、Deno公式サービス、Deno Deployをやってみた記録でした。
発表は2021/03/29だったとのことで、少し今更感はありますが、非常に簡単にアプリケーションを作れるサービスだと感じました。

今回はあまり高度なことはしていませんし、「コード書いてリポジトリ連携したら動いた」というだけの話ですが、 これってけっこうすごいこと だと思います。

これまでは、各種サーバーレスサービスにDenoの実行環境がない問題があり、そういった点を解決してくれるライブラリが存在しました。

例えば、vercel-denoに関しては以前に記事を書いています。
https://zenn.dev/kawarimidoll/articles/2659e69719b075

また、未だ記事にはまとめていませんが、deno-lambdaを使ったこともあります。
https://zenn.dev/kawarimidoll/scraps/44009b392ed9f2

これらに対し、Deno DeployはDenoで書いたコードがそのまま動きます。「コード書いてリポジトリ連携したら動いた」ができるのです。
これってけっこうすごいこと です。Deno公式のサービスなので当然といえば当然ですが。

現時点ではDeno Deployはbetaですが、Denoのサーバーレス実行環境として最初の選択肢となっていくことは確実でしょう。
今後も開発が盛り上がっていくのを期待したいです。

脚注
  1. deployctlが使えない場合は$PATH~/.deno/binが入っているか確認してください ↩︎

Discussion