StrongLoop が提供する Express と Node.js に関する研修

StrongLoop / IBMによって提供されるこの翻訳.

本書は、英語の資料と比較すると古くなっている可能性があります。最新の更新については、英語版の資料を参照してください。

ルーティング

ルーティング とは、アプリケーション・エンドポイント (URI) と、クライアント要求に対するそれらの応答の定義のことです。 ルーティングの概要については、基本的なルーティングを参照してください。

次のコードは、極めて基本的なルートの例です。


var express = require('express');
var app = express();

// respond with "hello world" when a GET request is made to the homepage
app.get('/', function(req, res) {
  res.send('hello world');
});

route メソッド

route メソッドは、いずれかの HTTP メソッドから派生され、express クラスのインスタンスに付加されます。

次のコードは、アプリケーションのルートへの GET メソッドと POST メソッドに定義されたルートの例です。


// GET method route
app.get('/', function (req, res) {
  res.send('GET request to the homepage');
});

// POST method route
app.post('/', function (req, res) {
  res.send('POST request to the homepage');
});

Express は、HTTP メソッドに対応する以下のルーティング・メソッドをサポートします。getpostputheaddeleteoptionstracecopylockmkcolmovepurgepropfindproppatchunlockreportmkactivitycheckoutmergem-searchnotifysubscribeunsubscribepatchsearch、および connect

無効な JavaScript 変数名に変換されるメソッドをルーティングするには、大括弧の表記を使用します。例えば、app['m-search']('/', function ... を使用します。

どの HTTP メソッドからも派生されない app.all() という特殊なルーティング・メソッドがあります。このメソッドは、すべての要求メソッドのパスにミドルウェア関数をロードするために使用されます。

次の例では、http モジュールでサポートされている GET、POST、PUT、DELETE、またはその他の HTTP 要求メソッドのいずれを使用している場合でも、ハンドラーは「/secret」への要求に対して実行されます。


app.all('/secret', function (req, res, next) {
  console.log('Accessing the secret section ...');
  next(); // pass control to the next handler
});

ルート・パス

ルート・パスは、要求メソッドとの組み合わせにより、要求を実行できるエンドポイントを定義します。ルート・パスは、ストリング、ストリング・パターン、または正規表現にすることができます。

Express は、ルート・パスのマッチングに path-to-regexp を使用します。ルート・パスの定義におけるすべての可能性については、path-to-regexp 資料を参照してください。Express Route Tester は、パターン・マッチングをサポートしていませんが、基本的な Express ルートをテストするための便利なツールです。

照会ストリングは、ルート・パスの一部ではありません。

次に、ストリングに基づくルート・パスの例を示します。

このルート・パスは、要求をルートのルート / にマッチングします。


app.get('/', function (req, res) {
  res.send('root');
});

このルート・パスは、要求を /about にマッチングします。


app.get('/about', function (req, res) {
  res.send('about');
});

このルート・パスは、要求を /random.text にマッチングします。


app.get('/random.text', function (req, res) {
  res.send('random.text');
});

次に、ストリング・パターンに基づくルート・パスの例を示します。

このルート・パスは、acd および abcd をマッチングします。


app.get('/ab?cd', function(req, res) {
  res.send('ab?cd');
});

このルート・パスは、abcdabbcdabbbcd などをマッチングします。


app.get('/ab+cd', function(req, res) {
  res.send('ab+cd');
});

このルート・パスは、abcdabxcdabRABDOMcdab123cd などをマッチングします。


app.get('/ab*cd', function(req, res) {
  res.send('ab*cd');
});

このルート・パスは、/abe および /abcde をマッチングします。


app.get('/ab(cd)?e', function(req, res) {
 res.send('ab(cd)?e');
});

文字 ?、+、*、および () は、正規表現文字のサブセットです。ハイフン (-) およびドット (.) は、ストリングに基づくパスによってそのまま解釈されます。

次に、正規表現に基づくルート・パスの例を示します。

このルート・パスは、ルート名に「a」が含まれるすべてのものをマッチングします。


app.get(/a/, function(req, res) {
  res.send('/a/');
});

このルート・パスは、butterfly および dragonfly をマッチングしますが、butterflymandragonfly man などはマッチングしません。


app.get(/.*fly$/, function(req, res) {
  res.send('/.*fly$/');
});

ルート・ハンドラー

要求を処理するために、ミドルウェアのように動作する複数のコールバック関数を指定できます。唯一の例外は、これらのコールバックが next('route') を呼び出して、残りのルート・コールバックをバイパスすることです。このメカニズムを使用して、ルートに事前条件を適用し、現在のルートで続行する理由がない場合に後続のルートに制御を渡すことができます。

次の例に示すように、ルート・ハンドラーの形式は、関数、関数の配列、または両方の組み合わせにすることができます。

単一のコールバック関数で 1 つのルートを処理できます。次に例を示します。


app.get('/example/a', function (req, res) {
  res.send('Hello from A!');
});

複数のコールバック関数で 1 つのルートを処理できます (必ず、next オブジェクトを指定してください)。次に例を示します。


app.get('/example/b', function (req, res, next) {
  console.log('the response will be sent by the next function ...');
  next();
}, function (req, res) {
  res.send('Hello from B!');
});

コールバック関数の配列で 1 つのルートを処理できます。次に例を示します。


var cb0 = function (req, res, next) {
  console.log('CB0');
  next();
}

var cb1 = function (req, res, next) {
  console.log('CB1');
  next();
}

var cb2 = function (req, res) {
  res.send('Hello from C!');
}

app.get('/example/c', [cb0, cb1, cb2]);

独立した関数と関数の配列の組み合わせで 1 つのルートを処理できます。次に例を示します。


var cb0 = function (req, res, next) {
  console.log('CB0');
  next();
}

var cb1 = function (req, res, next) {
  console.log('CB1');
  next();
}

app.get('/example/d', [cb0, cb1], function (req, res, next) {
  console.log('the response will be sent by the next function ...');
  next();
}, function (req, res) {
  res.send('Hello from D!');
});

応答メソッド

次の表に示す応答オブジェクト (res) のメソッドは、応答をクライアントに送信して、要求と応答のサイクルを終了することができます。これらのメソッドのいずれもルート・ハンドラーから呼び出されない場合、クライアント要求はハングしたままになります。

メソッド 説明
res.download() ファイルのダウンロードのプロンプトを出します。
res.end() 応答プロセスを終了します。
res.json() JSON 応答を送信します。
res.jsonp() JSONP をサポートする JSON 応答を送信します。
res.redirect() 要求をリダイレクトします。
res.render() ビュー・テンプレートをレンダリングします。
res.send() さまざまなタイプの応答を送信します。
res.sendFile ファイルをオクテット・ストリームとして送信します。
res.sendStatus() 応答の状況コードを設定して、そのストリング表現を応答本文として送信します。

app.route()

app.route() を使用して、ルート・パスのチェーン可能なルート・ハンドラーを作成できます。 パスは単一の場所で指定されるため、モジュール式のルートを作成すると、便利であるほか、冗長性とタイプミスを減らすことができます。ルートについて詳しくは、Router() 資料を参照してください。

次に、app.route() を使用して定義された、チェーニングされたルート・ハンドラーの例を示します。


app.route('/book')
  .get(function(req, res) {
    res.send('Get a random book');
  })
  .post(function(req, res) {
    res.send('Add a book');
  })
  .put(function(req, res) {
    res.send('Update the book');
  });

express.Router

モジュール式のマウント可能なルート・ハンドラーを作成するには、express.Router クラスを使用します。Router インスタンスは、完全なミドルウェアおよびルーティング・システムです。そのため、よく「ミニアプリケーション」と呼ばれます。

次の例では、ルーターをモジュールとして作成し、その中にミドルウェア関数をロードして、いくつかのルートを定義し、ルート・モジュールをメインアプリケーションのパスにマウントします。

アプリケーション・ディレクトリーに次の内容で birds.js というルーター・ファイルを作成します。


var express = require('express');
var router = express.Router();

// middleware that is specific to this router
router.use(function timeLog(req, res, next) {
  console.log('Time: ', Date.now());
  next();
});
// define the home page route
router.get('/', function(req, res) {
  res.send('Birds home page');
});
// define the about route
router.get('/about', function(req, res) {
  res.send('About birds');
});

module.exports = router;

次に、ルーター・モジュールをアプリケーションにロードします。


var birds = require('./birds');
...
app.use('/birds', birds);

これで、アプリケーションは、/birds および /birds/about に対する要求を処理するほか、ルートに固有の timeLog ミドルウェア関数を呼び出すことができるようになります。