情報アイランド

「情報を制する者は世界を制す」をモットーに様々な情報を提供することを目指すブログです。現在はプログラミング関連情報が多めですが、投資関連情報も取り扱っていきたいです。

expressモジュールによるHTTPサーバ(2)ミドルウェア

この記事は「expressモジュールによるHTTPサーバ」という連載記事の2つ目の記事です。

その他の記事に関しては下を参照してください。

この記事ではexpressモジュールを使ってアプリケーションにミドルウェアを追加する方法を説明します。

ミドルウェアとは

ミドルウェアとは特定のHTTPリクエストに対して何らかの処理を実行するものです。

ミドルウェアには普通のミドルウェアとエラーを処理するための特別なミドルウェアがあります。

ミドルウェアはアプリケーションに追加されたのと同じ順番で処理が実行されます。ただし、処理の実行中にエラーが発生した場合にはエラーが発生したミドルウェアから次のエラー処理ミドルウェアまでの間のミドルウェアの処理は実行されません。

ミドルウェアの追加

アプリケーションにミドルウェアを追加するにはapp.use関数を使用します。

var express = require('express');

var app = express();
app.use('xxx', function (req, res, next) {
    next();
    //or
    next(new Error('aaa'));
});

第1引数

第1引数にパスを指定します。この引数は指定しなくても構いません。

リクエストURLのパス部分の先頭部分がこのパスに合致する場合にはリクエストに対してミドルウェアの処理が実行されます。

ただし、パスを指定しなかった場合には全てのリクエストに対して処理が実行されます。

パスの指定方法としては単純な文字列のパス、パスパターン、正規表現(RegExpクラスのインスタンス)、配列があります。

配列により複数のパスを指定することができます。

パスパターンにおいては下のようなパターンを使用することができます。

  • ?・・・直前の文字又は()に囲まれた文字列が0回又は1回出現することを示します。
  • +・・・直前の文字又は()に囲まれた文字列が1回以上連続して出現することを示します。
  • *・・・任意の文字列を示します。

第2引数

第2引数にミドルウェアの処理を関数として指定します。

この関数の第1引数はクライアントに関する情報やクライアントからのHTTPリクエストの内容などを表すexpress.Requestクラスのインスタンスです。この引数の名称はreq(requestの省略)とされることが多いです。以後この引数をreqと表記します。

第2引数はクライアントに返すHTTPレスポンスの内容を表すexpress.Responseクラスのインスタンスです。この引数の名称はres(responseの省略)とされることが多いです。以後この引数をresと表記します。

第3引数は次のミドルウェアを呼び出すための関数です。この引数の名称はnext(「次」という意味から)とされることが多いです。以後この引数をnextと表記します。

ミドルウェアの処理が完了した場合にはnext()という風にnext関数を呼び出すことにより次のミドルウェアの処理に移ります。

あるいは、next関数の第1引数にエラーオブジェクトを指定することもできます。これによりミドルウェアの処理においてエラーを発生させることができます。

next関数を呼び出さないと次のミドルウェアの処理に移ることはありませんので注意してください。

ただし、ミドルウェアの処理においてHTTPレスポンスを送信した場合には通常は次のミドルウェアの処理に移る必要はありません(つまり、next関数を呼び出す必要はありません)。

その他

複数のミドルウェアを一度のapp.use関数の呼び出しでアプリケーションに追加することもできます。

その場合には第3引数以降にミドルウェアの処理を関数として指定します。

あるいは、第2引数以降に複数のミドルウェアの処理を関数の配列として指定することもできます。

ただし、一度のapp.use関数の呼び出しで追加された複数のミドルウェアはグループ化され、ミドルウェアの処理においてnext('route')という風にnext関数を呼び出すことにより同じグループの以後のミドルウェアの処理を飛ばすことができます

なお、複数のミドルウェアは指定したのと同じ順番でアプリケーションに追加されます。

エラー処理ミドルウェアの追加

アプリケーションにエラー処理ミドルウェアを追加するにも普通のミドルウェアの場合と同じくapp.use関数を使用します。

app.use('xxx', function (err, req, res, next) {
    next();
    //or
    next(new Error('aaa'));
});

普通のミドルウェアの場合とほぼ同じですが、第2引数の関数の第1引数の前にエラーオブジェクトが入ります。

これによりエラーを処理することができます。

未処理のエラー

リクエストの処理においてエラー処理ミドルウェアによっても処理されない未処理のエラーが発生した場合には自動的にステータスが500 Internal Server ErrorのHTTPレスポンスが送信されます

env設定項目の値がdevelopmentである場合には送信されるHTTPレスポンスのボディにはスタックトレースが含められます。productionの場合には含められません。

パスに関する設定項目

パスに関するアプリケーションの設定項目として下の2つがあります。

  • case sensitive routing・・・パスの大文字と小文字を区別するかを真偽値として設定します。デフォルトはfalseです。
  • strict routing・・・パスの末尾が/である場合にこの/ないものと見做さないかを真偽値として設定します。デフォルトはfalseです。

サンプルコード1

クライアントからリクエストを受け取ったら標準出力にメッセージを出力するHTTPサーバを作成し、起動します。

Enterキーが押されたらサーバを停止し、プログラムを終了します。

express-server-use.js

var express = require('express');

var app = express();
app.set('env', 'development');
app.set('x-powered-by', false);
app.set('case sensitive routing', true);
app.set('strict routing', true);
app.use(function (req, res, next) {
    console.log('requested.');
    next();
});
var server = app.listen(3000, function () {
    console.log('http server is running...press enter key to exit.');

    process.stdin.on('data', function (data) {
        if (data.indexOf('\n') !== -1) {
            server.close(function () {
                console.log('http server closed.');
                process.exit(0);
            });
        }
    });
});
server.on('error', function (err) {
    console.error(err);
    process.exit(1);
});

使用パッケージ

  • express
    npm install expressでインストールします。

実行結果

実行結果の確認のためにcURLを使用しています。

コードを実行するとHTTPサーバが起動します。

C:\work\node>node express-server-use.js
http server is running...press enter key to exit.

cURLを使ってサーバに対してHTTPリクエストを行います。

C:\work\node>curl -v http://localhost:3000/
*   Trying ::1...
* Connected to localhost (::1) port 3000 (#0)
> GET / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.46.0
> Accept: */*
>
< HTTP/1.1 404 Not Found
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 13
< Date: Tue, 05 Jul 2016 09:18:47 GMT
< Connection: keep-alive
<
Cannot GET /
* Connection #0 to host localhost left intact

メッセージが正しく出力されていることが分かります。

C:\work\node>node express-server-use.js
http server is running...press enter key to exit.
requested.

Enterキーを押すとサーバが停止し、プログラムが終了します。

関連

pizyumi
プログラミング歴19年のベテランプログラマー。業務システム全般何でも作れます。現在はWeb系の技術を勉強中。
スポンサーリンク

-express, Node.js