皆さんこんにちは、積みを重ねています。おっくんです。
Deno の アプリケーションをホスティングしてくれる Deno Deploy が、2021 年 03 月 29 日に公開されました。 毎度 Deno のリリース内容を追いかけている本ブログでも Deno Deploy を試してみたいと思います。
その前に...
2021 年 03 月 29 日 に Deno Deploy の公開と同じタイミングで、Deno が会社に変わりました。
この中でポイントになるのが、以下の 2 点だと思います。
- Deno のライセンスは、MIT を維持する
- 商用アプリケーションを構築できるインフラを提供する
ライセンスに変更が無いので、今後も存分に Deno を使えることがありがたい限りです。 そして商用サービス構築の入口が、今回の Deno Deploy になるようです。
Pricing & Limitsを見ると Deno Deploy のパブリックベータ期間が終了すると詳細な価格が示されるとしています。
Deno Deploy で動くアプリケーションを作ってみる
まずはローカルで
最終的には、Deno Deploy にデプロイしますが、まずはローカルで動作確認してみます。
次のコマンドで、deployctl
をインストールできます。
deno install --allow-read --allow-write --allow-env --allow-net --allow-run --no-check -f https://deno.land/x/deploy/deployctl.ts
deployctl の実行は、Deno 1.9.1 が必須なので、1.9.0 以前のバージョンを使用している場合には、deno upgrade
しましょう
error: The Deno version you are using is too old. Please update to Deno 1.9.1 or later. To do this run `deno upgrade`.
コマンドを確認します。
$ deployctl -h deployctl 0.3.0 Run Deno Deploy scripts locally. To run a script locally: deployctl run https://deno.land/x/deploy/examples/hello.js To run a script locally and watch changes: deployctl run --watch https://deno.land/x/deploy/examples/hello.js SUBCOMMANDS: run Run a script given a filename or url check Perform type checking of the script without actually running it types Print the Deno Deploy TypeScript declarations upgrade Upgrade deployctl to the given version (defaults to latest)
例に倣って実行してみます。
$ deployctl run https://deno.land/x/deploy/examples/hello.js Check file:///Users/developer/dev/deno3/$deno$eval.ts Check data:application/typescript;base64,aW1wb3J0IHR5cGUge30gZnJvbSAiZmlsZTovLy9Vc2Vycy9kZXZlbG9wZXIvTGlicmFyeS9DYWNoZXMvZGVuby9odHRwcy9kZW5vLmxhbmQvMzg5NzYyNTc4ZGYyYThhZTBhNmQxODk1ZDUxYWYxNWNjZDE3MWI4MTIxM2NiZWY0NDg0YzQxNDUyMmZjMTQyZi50cyI7aW1wb3J0IHR5cGUge30gZnJvbSAiZmlsZTovLy9Vc2Vycy9kZXZlbG9wZXIvTGlicmFyeS9DYWNoZXMvZGVuby9odHRwcy9kZW5vLmxhbmQvYTU0ODczY2U3NDU0OTE5NDJhYmRlODg3NGI1ZWE5MmYzNDNhOWJlNGE1NDEzZTc4ZGZlN2M5NGZjZmUyYjIwMS50cyI7aW1wb3J0IHR5cGUge30gZnJvbSAiZmlsZTovLy9Vc2Vycy9kZXZlbG9wZXIvTGlicmFyeS9DYWNoZXMvZGVuby9odHRwcy9kZW5vLmxhbmQvNzQ2N2JjNzY2Mzg4MGI1MzM5ZjM2ZWUwYWQ2ZGNiY2QzNDljMmI5YzM5NmE0OGI0MDYxNjc5YzNiZWNkMTNiMi50cyI7aW1wb3J0ICJodHRwczovL2Rlbm8ubGFuZC94L2RlcGxveS9leGFtcGxlcy9oZWxsby5qcyI7 Listening on http://0.0.0.0:8080
http://0.0.0.0:8080
にアクセスすると、Hello world!
と表示されます。
deployctl を使って、アプリケーションを実行できました。
アプリケーションの作り方を確認
実行できることはわかったので、続けて自前でアプリケーションを作ってみます。
hello-worldの内容を確認します。
アプリケーションは、必ず addEventListener
で fetch
イベントをリッスンし、コールバック関数で処理させる必要があります。
addEventListener("fetch", (event) => { /* handle the FetchEvent here */ });
シンプルにHello World!
を返すだけのサンプルは、以下のようになっています。
addEventListener("fetch", (event) => { const response = new Response("Hello World!", { headers: { "content-type": "text/plain" }, }); event.respondWith(response); });
先に実行した https://deno.land/x/deploy/examples/hello.js
は、内容が少し異なっていたので、こちらも見ておくと理解が深まると思います。
addEventListener("fetch", (event) => { event.respondWith( new Response("Hello world!", { status: 200, headers: { server: "denosr", "content-type": "text/plain", }, }) ); });
そのほかの実装例も充実しているので、これだけでかなり参考になります。
自前でアプリケーションを作る
今回は、デプロイができることを試したいので、簡単なものにとどめておきます。 アクセスすると、現在の日付と時刻を返すアプリケーションを作ります。
以下のソースコードを用意しました。
[main.ts]
addEventListener("fetch", (event) => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request: Request) { const date = new Date(); const dateString = date.toLocaleDateString("ja-JP", { weekday: "long", year: "numeric", month: "long", day: "numeric", }); const timeString = date.toLocaleTimeString("ja-JP", { hour12: false, }); const message = `${dateString} ${timeString}`; const response = new Response(message, { headers: { "content-type": "text/plain;charset=utf-8", }, }); return response; }
Deno Deploy にデプロイする
先に作成したアプリケーションを Deno Deploy にデプロイしてみます。
まずログイン
Deno Deploy にログインしましょう。GitHub 連携が使えます。
ログインすると以下の画面になります。
プロジェクト作成
プロジェクト名はランダムに生成してくれるので、今回はそのまま使います。
デプロイ元の指定
GitHub 連携を使う記事をよく見かけるので、Deploy URL
を使う方法を紹介したいと思います。
Deploy URL
を選択します。
main.ts
を任意のサーバーにアップロードし参照できる状態にします。
公開している main.ts
の URL を登録して Deploy します。
一瞬デプロイ画面が表示され、次の結果画面に遷移します。
ドメインが記載されているので、そちらにアクセスしてみます。
アクセスしてレスポンスを確認できました。 時刻がUTC になっているので、日本時間を取得できるように改修して更新してみます。
更新する
前述の通り Deno Deploy の実行基盤は UTC でした。日本時間を取得できるよう以下の通り改修します。
[main.ts]
addEventListener("fetch", (event) => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request: Request) { const date = new Date(); const dateString = date.toLocaleDateString("ja-JP", { timeZone: "Asia/Tokyo", // タイムゾーン設定を追加 weekday: "long", year: "numeric", month: "long", day: "numeric", }); const timeString = date.toLocaleTimeString("ja-JP", { timeZone: "Asia/Tokyo", // タイムゾーン設定を追加 hour12: false, }); const message = `${dateString} ${timeString}`; const response = new Response(message, { headers: { "content-type": "text/plain;charset=utf-8", }, }); return response; }
改めて、deploy URL
から最初と同じようにデプロイします。
デプロイ後に再度アクセスすると、日本時間になっていました。 無事更新できました。
ログ
Deno Deploy のログは、console API で出力することができます。
ソースコードを次のように直してデプロイします。
[main.ts]
addEventListener("fetch", (event) => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request: Request) { const date = new Date(); const dateString = date.toLocaleDateString("ja-JP", { timeZone: "Asia/Tokyo", // タイムゾーン設定を追加 weekday: "long", year: "numeric", month: "long", day: "numeric", }); const timeString = date.toLocaleTimeString("ja-JP", { timeZone: "Asia/Tokyo", // タイムゾーン設定を追加 hour12: false, }); // アクセス時刻としてログ出力 const message = `${dateString} ${timeString}`; console.log(`access: ${message}`); const response = new Response(message, { headers: { "content-type": "text/plain;charset=utf-8", }, }); return response; }
デプロイできたら、Logs
を開きます。
console.log
で出力した内容を確認できます。
ログレベルや、タイムスタンプも出せるので、実は今回のようにアクセス時刻をわざわざ残す必要はなかったりします。
現在の Deno Deploy
現在の Deno Deploy は、DB 機能を提供していません。データの永続化を外部のサービスに依存しています。 ドキュメントでは、 DB を使用する例として FaunaDB と AWS DynamoDB などの使い方を紹介しています。
詳細に手順が書かれているので順を追って進めれば、大きな苦労なくアプリケーションの構築ができるでしょう。
専用の DB も無い現状ですので、Redis などのキャッシュに使うようなインフラもありません。
こういったインフラがない現状なので、Deno Deploy だけで「なんでもできるという状況」ではありませんが、例えば AWS lambda で API を公開するようなユースケースで、「TypeScript で書きたい!」というニーズには非常に活躍するのではないでしょうか?
また注意点としては、Deno の API と Deno Deploy に公開されている API は一致しない点です。
例えば、次のソースコードは意図したよう動きません。
[version.ts]
addEventListener("fetch", (event) => { event.respondWith(handleRequest(event.request)); }); async function handleRequest(request: Request) { const message = `version: ${JSON.stringify((<any>Deno).version)}`; const response = new Response(message, { headers: { "content-type": "text/plain;charset=utf-8", }, }); return response; }
deployctl を用いてローカルで動作させると、以下のように表示されますが、
Deno Deploy では、次のようになります。
API リファレンスに記載があるのですが、Deno DeployRuntime がサポートしている Deno API しか使えないので、確認しておくことは大事です。
今回は Deno Deploy を試しました。
Deno Deploy は、始まったばかりのパブリックベータです。
実行環境を用意するということで、「これからの オープンソースソフトウェア の開発は、実行環境も提供していかないと普及できないのか」と思っています。
特に、サーバーサイドJavaScript、TypeScript の実行環境としては、Node.js もあることを考えれば、それくらいのアピールやインパクトが必要なのかもしれません。
これからが楽しみなので、Deno 本体のリリースと併せて追いかけて行きたいと思います。
P.S.
■ 採用情報
とらのあなでは、オタクなエンジニアを募集しています。
yumenosora.co.jp
カジュアル面談も随時開催中です。お申し込みはこちら!
yumenosora.connpass.com
■ ToraLab.fmスタートしました!
メンバーによるPodcastを配信中!是非スキマ時間に聞いて頂けると嬉しいです。
anchor.fm
■ Twitterもフォローしてくださいね!
ツイッターでも随時情報発信をしています。
twitter.com