こちらはDeno Advent Calendar一日目の記事です。
Denoが登場して早一年半ともなりますが、まだ触ったことの無い方も多いのではないでしょうか?
最初の一歩で何を作るか、と言うのはいつも悩ましいですが、
やっぱりここはみんな大好きWebアプリケーションかな?と言う事で、簡単なWebアプリケーションをDenoで作って動かす方法を紹介します。
今回使うmodule
の2つを使います。
※なお、dinatraは内部的にdeno_stdのhttp serverを使用していますが、まだ不安定なため、より安定したWebサーバーの構築をされたい方にはkeroxpさんのservestをオススメします。
dinatraを使ったWebアプリの最小構成
まず、Denoをインストール済みと言う前提で話を進めます。
dinatraアプリは下記の内容を保存したtsファイルをDenoで実行することで動作します。
import { app, get } from 'https://denopkg.com/syumai/dinatra/mod.ts';
app(get('/hello', () => 'hello'));
dinatraのハンドラーは、登録したいHTTPメソッド名の関数に、パスと、返すコンテンツ(string | Deno.Reader)を渡してやることで登録が出来ます。
試しに、この内容を example.ts
として保存して実行してみましょう。
なお、Denoはファイルアクセスや、ネットワークへのアクセスに権限の許可を必要とするので、 --allow-net
を指定している点にご注意ください。
$ deno --allow-net example.ts
listening on http://0.0.0.0:8080/
次に、今起動したDenoのHTTPサーバーに対してブラウザやcurlでアクセスしてみましょう。
$ curl localhost:8080/hello
hello
ちゃんと hello
と言う文字列が表示されるのが確認できましたね!
dinatraの基本的な使い方はたったこれだけです。
postやput, patch, deleteメソッドのハンドラを登録したければ、それらをimportしてapp関数に渡せばOKです。
(※deleteについては言語の制約上、 del
と言う名前になっています)
その他の詳しい使い方については公式のREADMEを参照ください。
dinatraでPOSTの送信を受け取る
次に、Formで送信した内容をDenoのサーバー側で取得するサンプルを作ってみます。
受け付けたいのはPOSTリクエストです。
なので、POSTハンドラ登録用の関数をimportします。
また、ルート (localhost:8080) へのアクセスがされたら、テンプレートのHTMLを表示するようにします。
このHTMLには、フォームとメッセージ表示領域を用意して、フォームが送信されたらメッセージを表示するようにします。
イメージはこちらです。
今回は、EJSで作ったViewのファイルと、サーバーとを分離してみます。
Viewは次のような内容になっています。
<html>
<head>
<meta charset="utf-8">
<title>Deno form example</title>
</head>
<body>
<form action="/posts" method="POST">
<label>メッセージを入れてね!</label><br>
<input type="text" name="message" placeholder="message" /><br>
<button>送信</button>
</form>
<div>受け取ったメッセージ: <%= message %></div>
</body>
</html>
サーバーは次のような内容になっています。
import { app, get, post } from 'https://denopkg.com/syumai/dinatra/mod.ts';
import { renderFile } from 'https://deno.land/x/dejs@0.3.3/mod.ts';
const templatePath = `${Deno.cwd()}/index.ejs`;
app(
get('/', async () => await renderFile(templatePath, { message: '' })),
post(
'/posts',
async ({ params: { message } }) =>
await renderFile(templatePath, { message })
)
);
dinatraでは、ハンドラに登録するレスポンスの形式として、Deno.Readerを返すasync functionをサポートしています。
dejsのrenderFileは、Deno.Readerを返すasync functionなので、これを使用してViewの描画を行っています。
では、上記の2ファイルをそれぞれ index.ejs
, mod.ts
として保存し、次のように実行してみましょう。
$ deno --allow-net --allow-read mod.ts
この状態で localhost:8080
にアクセスすると、フォームが動作することが確認出来ると思います!
ぜひ、今回の内容をカスタマイズして、Denoで動作するWebアプリケーションを作ってみてください!
これをもっとちゃんとした雰囲気の掲示板アプリにしたDenoboardがあるので、興味がある方はこちらもご覧ください。
Denoに関する質問があれば、deno-jaのSlackに投げるとガシガシ回答が付いていくと思います。
これから28日、全ては埋まっていないですが、Denoに関する記事がガンガン投下されていくと思うとワクワクしますね!
明日は@hashrockさんの記事です!
それでは皆さん、楽しいDeno Lifeを!
補足
- 実は今回の内容では
Content-Type: text/html
を送るのもサボっています。ちゃんとやる方法は公式のREADMEに記載があります