astamuse Lab

astamuse Labとは、アスタミューゼのエンジニアとデザイナーのブログです。アスタミューゼの事業・サービスを支えている知識と舞台裏の今を発信しています。

はじめてのExpress.js 〜導入編〜

こんにちは。デザイン部でフロントエンドエンジニアをしているkitoです。
今回から数回に渡って、Node.jsのWebフレームワークExpress.jsのご紹介をしていきたいと思います。

はじめに

数多く存在するのWebフレームワークのなかから、Node.jsのフレームワークを導入する理由をあげるとすれば何があるでしょうか? 有力な理由のひとつは、PayPal社の事例 でもわかるように、共通のプログラミング言語、つまりJavaScriptをブラウザ側とサーバ側両方で活用することで、フロントエンドとバックエンドの垣根を取り払い、ひとつのチームで両方の問題に素早く対応できるようにすることがあげられます。これは「Isomorphic」あるいは最近では「Universal」なアプリケーションと呼ばれています。

もちろん、Universalなアプリケーションが常プラスに働くとは限りません。ひとつのチームではなく複数チームにタスクを分担することで開発効率をあげるやり方(基本的に弊社もこの方式です)は、スケールしやすく複雑な問題に対応できます。とはいえ、Universalなアプリケーションなら、開発、運用、改善のサイクルを迅速に回すことができ、それによってアプリケーションの質を高めつつ柔軟に外部環境の変化に対応できます。身軽なWebアプリケーション開発と運用に最優先にするなら、Node.jsのフレームワークを選択することは、適材適所という意味で理にかなっているでしょう。
本稿では、Node.jsのフレームワークのなかでもデファクトスタンダードなExpress.jsを詳しく説明していきますが、もうひとつの有力フレームワークであるSails.jsと比較してみると、Express.jsの輪郭を把握しやすくなるでしょう。

Express.jsの特長

Express.jsは軽量でシンプルなマイクロフレームワークです。 公式サイトでは『特定の意見に固執しない、Node.js向けの高速で最小限のWebフレームワーク』と謳われています。Rubyのフレームワークで例えるなら、Sinatraに似ています。 公式サイト

Sails.jsの特長

Sails.jsはExpress.jsをベースにつくられています。Express.jsがSinatraライクなフレームワークであるとするなら、Sails.jsは名前からもわかる通りRuby and Railsライクな比較的重量級のフレームワークです。Railsよろしくsails generateコマンドでmodelやcontrollerを作成できます。RESTfulなJSON APIが自動生成されるのでデータドリブンなアプリケーションに向いています。また、WaterlineというORMを備えています。 公式サイト

Sails.jsを仮に導入するとしても、その元になっているExpress.jsを学んでおいた方が理解が早まるでしょう。またSails.jsのWaterlineはモジュール化されているのでExpress.jsでも利用できます。

Node.jsのインストール

Express.jsをインストールするには、Node.jsが必須です。Node.jsをインストールされていない方はインストールしましょう。 Node.jsの公式サイトからインストールできます。 Macを使われていてHomebrewを導入済みなら、以下のコマンドをターミナルで実行してインストールできます。

brew install node

インストールできたらバージョンを確認してみましょう。 Windowsならコマンドプロンプト、Macならターミナルから以下を実行します。

node -v

本稿では、最新バージョンであるv6.2.0を前提にして進めます。

Node.jsをインストールできたので、同時にnpmというパッケージ管理システムがインストールされました。 npmを使ってExpress.jsをインストールできるようになりましたが、ここでnpmについて説明します。

npm

npmはNode Package Managerの略で、Nodeモジュールを管理するツールです。Express.jsもこのNodeモジュールとして提供されているので、Express.jsを使う場合は、事実上は必須のツールと考えてよいでしょう。もっとも、利用するのにそれほど複雑なツールではありません。幾つかのコマンドを覚えれば迷わず使うことができるでしょう。 まず、myappというディレクトリを作成してnpmを初期化します。

mkdir myapp && cd myapp
npm init

上記をターミナルorコマンドプロンプト実行すると、インタラクティブにnameやdescriptionなどが聞かれます。後から修正できるのでまずはすべてEnterキーで良いでしょう。するとmyapp内にpackage.jsonというファイルが作成されます。ここにはモジュールの名前や依存関係が記述されていきます。 では、早速express.jsをnpmでインストールしてみましょう。 以下を実行すると、しばらく時間がかかりますがインストールできます。

npm install express --save

--saveは、npmのオプションのひとつで、これをつけてインストールするとpackage.jsonのdependenciesに依存関係が記述されます。また、--save-devオプションをつけると、devDependencieに依存関係が記述されます。

その他、よく使うnpmコマンドは以下のようなものがあります。 npmモジュールをグローバル領域にインストールする際に使います。

npm install -g モジュール名

installはiにた短縮可能です。

npm i モジュール名

モジュール名@バージョンで任意バージョンのインストールができます。

npm install express@4.13.4

モジュール名 -Vでインストールされているバーションを確認できます。

express -V
4.13.1

バージョンを確認できれば、express.jsがインストールされたことが確認できます。

Node.jsでつくるアプリケーション

Express.jsを動かしてみる前に、回り道のようですがExpress.jsを使わずにNode.jsだけ簡易なHTTPサーバーを作成してみましょう。 任意のフォルダを作成してください。その中にserver.jsというファイルを作成して、以下のコードを記述してください。

var http = require('http');

var server = http.createServer(function(req, res) {
   res.writeHead(200, {'Content-Type': 'text/plain'});
   res.write('Hello World!');
   res.end();
});

server.listen(3000, function () {
  console.log('listening on port 3000');
});

上記コードを説明します。
var http = require('http')でhttpモジュールを読み込み、HTTPサーバーのオブジェクトを作成しています。
httpモジュールはNode.jsのコアモジュールなので、Node.jsと一緒にインストールされています。改めてnpmでインストールする必要はありません。 そして、httpモジュールのcreateServerメソッドを使ってサーバーのを作成します。 引数のreqとresには、それぞれリクエストオブジェクトとレスポンスオブジェクトが渡さるので、コールバック関数に、リクエストがあるたびに呼ばれる処理を書いていきます。 res.writeHeadでステータスコードとHTTPレスポンスヘッダーを送信し、同様にres.writeでレスポンスの本体を送信します。res.endでレスポンスを終了します。 server.listenでは、リクエストの着信を待ち受け状態にしています。第1引数は待受けているportの番号を渡しています。

これを実行しましょう。

node server.js

そしてhttp://localhost:3000にアクセスし、Hello World!と表示されていれば成功です。

次に、上記のコードをURLに応じて処理先を変更できるように修正します。

var http = require('http');
var url = require("url");

var server = http.createServer(function(req, res) {
  var pathname = url.parse(req.url).pathname;

  if ('/' == pathname) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write('Hello World!');
    res.end();
  }

  if ('/user' == pathname) {
    //省略
  }

});

server.listen(3000, function() {
    console.log('listening on port 3000');
});

まず、require("url")でurlを解析するNodeコアモジュールを読み込みます。 これもNode.jsがインストールされた際に、一緒にインストールされているので改めてnpmからインストールする必要はありません。 url.parse(req.url).pathnameでリクエストしたURLのpathnameをとりだし、さらにif ('/' == pathname)でpathnameに応じて処理を分けます。

ただ上記ではHTTPリクエストのGETメソッドの処理しか書かれていません。これも書き分ける必要がでてくるでしょう。 まずserver.jsと同じ階層にindex.htmlを作成して以下を記述してください。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
    <h1>index</h1>
    <p>入力してください</p>
    <form method="post" action="/result">
        <input type="text" name="result">
        <input type="submit">
    </form>
</body>
</html>

HTTPリクエストのメソッドで処理を分岐させると、1例ですが下記のようになります。先ほどのserver.jsに上書きしてみましょう。

var http = require('http');
var url = require("url");
var fs = require('fs');
var querystring = require('querystring');

var server = http.createServer(function(req, res) {
  var pathname = url.parse(req.url).pathname;

  switch (pathname) {

    case '/':
      if (req.method === 'GET') {
        fs.readFile('./index.html', 'UTF-8', function(err, data){
          res.writeHead(200, {'Content-Type': 'text/html'});
          res.end(data);
        });
      }
    break;

    case '/result':
      if (req.method === 'POST') {
        var body = '';
        req.on('data', function(chunk) {
          body += chunk;
        });

        req.on('end',function(){
          var form = querystring.parse(body);
          var text = form.result;
            fs.readFile('./index.html', 'UTF-8', function(err, data){
                res.writeHead(200, {'Content-Type': 'text/html'});
                res.end('「'+ text + '」と入力しました。');
            });
        });
      }
    break;

  }
});

server.listen(3000, function() {
    console.log('listening on port 3000');
});

fsモジュールとquerystringモジュールは新しくインストール不要です。 fsモジュールはファイルを読み書きする際に必要です。上記では、fs.readFileでindex.htmlに読み書きするために使っています。 querystringは文字列をオブジェクトに変換するモジュールです。querystring.parse(body)でリクエストbodyを文字列からオブジェクトに変換しています。

pathnameで処理を分岐したうえで、さらにif (req.method === 'GET')とif (req.method === 'POST')でGETとPOSTに処理を分けています。 リクエストがあるたびにdataイベントが発火するので、onメソッドにバインドしてコールバック関数にリクエストがあったときの処理を記述しています。

req.on('data', function(chunk) {
  body += chunk;
});

上記ではPOSTメソッドのリクエストがあった際、formで渡されてきたchunkをbody変数に格納しています。 コードを実行して、http://localhost:3000にアクセスしてみましょう。 簡単なフォームが表示されたと思います。何らかの文字〇〇を入力して送信ボタンを押してみましょう。「〇〇」と入力しました。と表示されれば成功です。

まとめ

今回は、Express.jsの導入やNode.jsの概要に触れました。
やや回り道に思えたかもしれませんが、Express.jsで複雑なアプリケーションを作成しようとするならNode.jsの知識が必要になります。 Express.jsを使えば、冗長なアプリケーションを簡潔に記述することができます。
次回は、Express.jsについて詳しく見ていきます。

アスタミューゼでは、エンジニア・デザイナーを募集中です。ご興味のある方は遠慮なく採用サイトからご応募ください。お待ちしています。

 

Copyright © astamuse company, ltd. all rights reserved.