Express API の上書き

Express API は、リクエストオブジェクトとレスポンスオブジェクト上のさまざまなメソッドとプロパティで構成されています。これらはプロトタイプによって継承されます。Express API には 2 つの拡張ポイントがあります。

  1. express.requestexpress.response のグローバルプロトタイプ。
  2. app.requestapp.response のアプリ固有のプロトタイプ。

グローバルプロトタイプを変更すると、同じプロセス内の読み込まれたすべての Express アプリに影響します。必要に応じて、新しいアプリを作成した後にアプリ固有のプロトタイプのみを変更することで、変更をアプリ固有にすることができます。

メソッド

独自のカスタム関数を割り当てることで、既存のメソッドのシグネチャと動作を上書きすることができます。

次に、res.sendStatus の動作を上書きする例を示します。

app.response.sendStatus = function (statusCode, type, message) {
  // code is intentionally kept simple for demonstration purpose
  return this.contentType(type)
    .status(statusCode)
    .send(message)
}

上記のインプリメンテーションは、res.sendStatus の元のシグネチャを完全に変更します。現在、ステータスコード、エンコーディングタイプ、およびクライアントに送信されるメッセージを受け入れます。

上書きされたメソッドは、次の方法で使用できるようになりました。

res.sendStatus(404, 'application/json', '{"error":"resource not found"}')

プロパティ

Express API のプロパティには、次の 2 種類があります。

  1. 割り当てられたプロパティ(例: req.baseUrlreq.originalUrl
  2. ゲッターとして定義されたプロパティ(例: req.securereq.ip

カテゴリ 1 のプロパティは、現在のリクエストレスポンスサイクルのコンテキスト内の request オブジェクトと response オブジェクトに動的に割り当てられるため、その動作を上書きすることはできません。

カテゴリ 2 のプロパティは、Express API 拡張 API を使用して上書きできます。

次のコードは、req.ip の値の導出方法を書き換えます。これで、Client-IP リクエストヘッダーの値を返すだけです。

Object.defineProperty(app.request, 'ip', {
  configurable: true,
  enumerable: true,
  get () { return this.get('Client-IP') }
})

プロトタイプ

Express.js API を提供するには、Express.js に渡されるリクエスト/レスポンスオブジェクト(たとえば app(req, res))が同じプロトタイプチェーンから継承する必要があります。デフォルトでは、これはリクエストの場合 http.IncomingRequest.prototype、レスポンスの場合 http.ServerResponse.prototype です。

必要のない限り、これはグローバルに行うのではなく、アプリケーションレベルのみで行うことをお勧めします。また、使用されているプロトタイプが、できるだけデフォルトのプロトタイプと機能が一致するように注意してください。

// Use FakeRequest and FakeResponse in place of http.IncomingRequest and http.ServerResponse
// for the given app reference
Object.setPrototypeOf(Object.getPrototypeOf(app.request), FakeRequest.prototype)
Object.setPrototypeOf(Object.getPrototypeOf(app.response), FakeResponse.prototype)