Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
11
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

DenoでサクッとWebアプリケーションを立ち上げる

こちらはDeno Advent Calendar一日目の記事です。

Denoが登場して早一年半ともなりますが、まだ触ったことの無い方も多いのではないでしょうか?
最初の一歩で何を作るか、と言うのはいつも悩ましいですが、
やっぱりここはみんな大好きWebアプリケーションかな?と言う事で、簡単なWebアプリケーションをDenoで作って動かす方法を紹介します。

今回使うmodule

  • dinatra: Small web app framework for Deno
  • dejs: EJS engine for Deno

の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には、フォームとメッセージ表示領域を用意して、フォームが送信されたらメッセージを表示するようにします。

イメージはこちらです。

Screenshot from 2019-12-01 02-12-18.png

今回は、EJSで作ったViewのファイルと、サーバーとを分離してみます。

Viewは次のような内容になっています。

index.ejs
<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>

サーバーは次のような内容になっています。

mod.ts
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 にアクセスすると、フォームが動作することが確認出来ると思います!

Screenshot from 2019-12-01 02-21-23.png

ぜひ、今回の内容をカスタマイズして、Denoで動作するWebアプリケーションを作ってみてください!
これをもっとちゃんとした雰囲気の掲示板アプリにしたDenoboardがあるので、興味がある方はこちらもご覧ください。

Screenshot from 2019-12-01 02-53-19.png

Denoに関する質問があれば、deno-jaのSlackに投げるとガシガシ回答が付いていくと思います。

これから28日、全ては埋まっていないですが、Denoに関する記事がガンガン投下されていくと思うとワクワクしますね!
明日は@hashrockさんの記事です!
それでは皆さん、楽しいDeno Lifeを!

補足

  • 実は今回の内容では Content-Type: text/html を送るのもサボっています。ちゃんとやる方法は公式のREADMEに記載があります
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
11
Help us understand the problem. What are the problem?