Apigee Edge のドキュメントを表示しています。
Apigee X のドキュメントに移動。 情報
Edge CIDR v. 3.3.x
対象読者
このトピックは、カスタム プラグインを作成して Edge microme の機能を拡張したいデベロッパーを対象としています。新しいプラグインを作成する場合は、JavaScript と Node.js の使用経験が必要です。
カスタム Edge CIDR プラグインとは
プラグインは、Edge CIDR に機能を追加する Node.js モジュールです。プラグイン モジュールは一貫したパターンに従い、Edge CIDR に認識される場所に保存されるため、自動的に検出されて実行されます。Edge CIDR をインストールすると、事前定義されたプラグインがいくつか提供されます。これには、認証、Spike Arrest、割り当て、分析用のプラグインが含まれます。これらの既存のプラグインについては、プラグインを使用するをご覧ください。
カスタム プラグインを作成することで、Microgateway に新しい機能を追加できます。デフォルトでは、Edge CIDR は基本的に安全なパススルー プロキシであり、ターゲット サービスとの間でリクエストとレスポンスを変更せずに受け渡しします。カスタム プラグインを使用すると、Microgateway を通過するリクエストやレスポンスをプログラムで操作できます。
カスタム プラグイン コードを配置する場所
カスタム プラグイン用のフォルダは、Edge CIDR インストール環境の一部として、次の場所に配置されています。
[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins
ここで、[prefix]
は npm
接頭辞ディレクトリです。詳細については、Edge が表示される場所のインストールをご覧ください。
このデフォルトのプラグイン ディレクトリは変更できます。プラグインの場所をご覧ください。
事前定義されたプラグインを確認する
独自のプラグインを開発する前に、事前定義されたプラグインが要件に合っていないかどうかを確認することをおすすめします。これらのプラグインは次の場所にあります。
[prefix]/lib/node_modules/edgemicro/node_modules/microgateway-plugins
ここで、[prefix]
は npm
接頭辞ディレクトリです。Edge CIDR のインストールの「Edge CIDR のインストール場所」もご覧ください。
詳細については、Edge CIDR で提供される事前定義プラグインをご覧ください。
簡単なプラグインを作成する
このセクションでは、簡単なプラグインの作成に必要な手順を説明します。このプラグインは、レスポンス データ(内容にかかわらず)を文字列「Hello, World!」でオーバーライドし、ターミナルに出力します。
- Edge Dataprep が実行中の場合は、直ちに停止します。
edgemicro stop
-
cd
でカスタム プラグイン ディレクトリに移動します。cd [prefix]/lib/node_modules/edgemicro/plugins
ここで、
[prefix]
はnpm
接頭辞ディレクトリです。詳しくは、Edge が表示される場所のインストールをご覧ください。 - response-override という新しいプラグイン プロジェクトを作成し、
cd
でそのプロジェクトに作成します。
mkdir response-override && cd response-override
- 新しい Node.js プロジェクトを作成します。
npm init
Return を複数回押してデフォルト値を受け入れます。 - テキスト エディタを使用して、
index.js
という名前の新しいファイルを作成します。 - 次のコードを
index.js
にコピーし、ファイルを保存します。
'use strict'; var debug = require('debug') module.exports.init = function(config, logger, stats) { return { ondata_response: function(req, res, data, next) { debug('***** plugin ondata_response'); next(null, null); }, onend_response: function(req, res, data, next) { debug('***** plugin onend_response'); next(null, "Hello, World!\n\n"); } }; }
- プラグインを作成したので、このプラグインを Edge CIDR 構成に追加する必要があります。
$HOME/.edgemicro/[org]-[env]-config.yaml
ファイルを開きます。ここで、org
とenv
は Edge の組織名と環境名です。 - 以下に示すように、
response-override
プラグインをplugins:sequence
要素に追加します。
... plugins: dir: ../plugins sequence: - oauth - response-override ...
- Edge Dataprep を再起動します。
- Edge Dataprep を介して API を呼び出します。(この API 呼び出しは、Edge CIDR の設定と構成で説明されているように、API キー セキュリティに関するチュートリアルと同じ構成を設定していることを前提としています)。
curl -H 'x-api-key: uAM4gBSb6YoMvTHfx5lXJizYIpr5Jd' http://localhost:8000/hello/echo Hello, World!
プラグインの構造
次の Edge CIDR サンプル プラグインは、独自のプラグインを開発する場合のパターンを示しています。このセクションで説明するサンプル プラグインのソースコードは、plugins/header-uppercase/index.js.
にあります。
- プラグインは、ルートフォルダに
package.json
とindex.js
がある標準の NPM モジュールです。 - プラグインは init() 関数をエクスポートする必要があります。
- init() 関数は、config、logger、stats の 3 つの引数を取ります。これらの引数は、プラグインの init() 関数引数に記述されています。
- init() は、リクエストの存続期間中に特定のイベントが発生したときに呼び出される名前付き関数ハンドラを持つオブジェクトを返します。
イベント ハンドラ関数
プラグインでは、これらのイベント ハンドラ関数の一部またはすべてを実装する必要があります。これらの関数の実装は任意です。どの関数も省略可能です。一般的なプラグインでは、これらの関数の少なくとも一部が実装されます。
リクエスト フローのイベント ハンドラ
これらの機能は、Edge CIDR のリクエスト イベントで呼び出されます。
onrequest
ondata_request
onend_request
onclose_request
onerror_request
onrequest
関数
クライアント リクエストの開始時に呼び出されます。この関数は、Edge CIDR がリクエストの最初のバイトを受信すると起動します。この関数により、リクエスト ヘッダー、URL、クエリ パラメータ、HTTP メソッドにアクセスできます。信頼できる最初の引数(Error のインスタンスなど)を使用して next を呼び出すと、リクエストの処理は停止し、ターゲット リクエストは開始されません。
例:
onrequest: function(req, res, next) { debug('plugin onrequest'); req.headers['x-foo-request-start'] = Date.now(); next(); }
ondata_request
関数
クライアントからデータチャンクを受信したときに呼び出されます。プラグイン シーケンスの次のプラグインにリクエスト データを渡します。シーケンス内の最後のプラグインから返された値がターゲットに送信されます。次に示す一般的な使用例は、リクエスト データを変換してからターゲットに送信することです。
例:
ondata_request: function(req, res, data, next) { debug('plugin ondata_request ' + data.length); var transformed = data.toString().toUpperCase(); next(null, transformed); }
onend_request
関数
クライアントからすべてのリクエスト データを受信したときに呼び出されます。
例:
onend_request: function(req, res, data, next) { debug('plugin onend_request'); next(null, data); }
onclose_request
関数
クライアント接続が閉じたことを示します。この関数は、クライアント接続の信頼性が低い場合に使用できます。これは、クライアントへのソケット接続が閉じられたときに呼び出されます。
例:
onclose_request: function(req, res, next) { debug('plugin onclose_request'); next(); }
onerror_request
関数
クライアント リクエストの受信中にエラーが発生した場合に呼び出されます。
例:
onerror_request: function(req, res, err, next) { debug('plugin onerror_request ' + err); next(); }
レスポンス フローのイベント ハンドラ
これらの機能は、Edge CIDR のレスポンス イベントで呼び出されます。
onresponse
ondata_response
onend_response
onclose_response
onerror_response
onresponse
関数
ターゲット レスポンスの開始時に呼び出されます。この関数は、Edge CIDR がレスポンスの最初のバイトを受信したときに起動されます。この関数により、レスポンス ヘッダーとステータス コードにアクセスできます。
例:
onresponse: function(req, res, next) { debug('plugin onresponse'); res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start']) next(); }
ondata_response
関数
ターゲットからデータチャンクを受信したときに呼び出されます。
例:
ondata_response: function(req, res, data, next) { debug('plugin ondata_response ' + data.length); var transformed = data.toString().toUpperCase(); next(null, transformed); }
onend_response
関数
ターゲットからすべてのレスポンス データを受信したときに呼び出されます。
例:
onend_response: function(req, res, data, next) { debug('plugin onend_response'); next(null, data); }
onclose_response
関数
ターゲット接続が閉じたことを示します。ターゲット接続の信頼性が低い場合は、この関数を使用できます。このメソッドは、ターゲットへのソケット接続が閉じられたときに呼び出されます。
例:
onclose_response: function(req, res, next) { debug('plugin onclose_response'); next(); }
onerror_response
関数
ターゲット レスポンスの受信中にエラーが発生した場合に呼び出されます。
例:
onerror_response: function(req, res, err, next) { debug('plugin onerror_response ' + err); next(); }
プラグイン イベント ハンドラ関数について知っておくべきこと
プラグイン イベント ハンドラ関数は、Edge CIDR が特定の API リクエストを処理している間に発生する特定のイベントに応答して呼び出されます。
- 各 init() 関数ハンドラ(ondata_request、ondata_response など)は、処理の完了時に next() コールバックを呼び出す必要があります。next() を呼び出さないと、処理は停止し、リクエストはハングします。
- next() の最初の引数がエラーの場合、リクエストの処理が終了します。
- ondata_ ハンドラと onend_ ハンドラは、ターゲットまたはクライアントに渡すデータを含む 2 番目の引数を指定して、next() を呼び出す必要があります。プラグインがバッファリングしていて、その時点で変換するのに十分なデータがない場合は、この引数が null になることがあります。
- プラグインの単一のインスタンスを使用して、すべてのリクエストとレスポンスを処理します。プラグインで、呼び出し間でリクエストごとの状態を保持する場合、指定されたリクエスト オブジェクト(req)に追加されたプロパティにその状態を保存できます。その存続期間は API 呼び出しの期間です。
- すべてのエラーを注意深くキャッチし、そのエラーで next() を呼び出してください。next() の呼び出しに失敗すると、API 呼び出しがハングします。
- メモリリークを発生させないように注意してください。これは、Edge CIDR の全体的なパフォーマンスに影響を及ぼし、メモリが不足した場合にクラッシュを引き起こす可能性があります。
- Node.js モデルに従って、コンピューティング負荷の高いタスクをメインスレッドで実行しないように注意してください。これは、Edge CIDR のパフォーマンスに悪影響を及ぼす可能性があります。
プラグインの init() 関数について
このセクションでは、init() 関数に渡される引数(config、logger、stats)について説明します。
config
Edge Maven 構成ファイルを Apigee Edge からダウンロードしたデータと統合して取得された構成データは、config
という名前のオブジェクトに配置されます。
値が foo の param という構成パラメータを response-override というプラグインに追加するには、default.yaml
ファイルに次の行を追加します。
response-override: param: foo
その後、次のように、プラグイン コードでパラメータにアクセスできます。
// Called when response data is received ondata_response: function(req, res, data, next) { debug('***** plugin ondata_response'); debug('***** plugin ondata_response: config.param: ' + config.param); next(null, data); },
この場合、プラグインのデバッグ出力に foo が表示されます。
Sun, 13 Dec 2015 21:25:08 GMT plugin:response-override ***** plugin ondata_response: config.param: foo
子オブジェクト config.emgConfigs
で、統合した microgateway の構成とダウンロードした Apigee Edge データにアクセスできます。たとえば、次のように init
関数でこの構成データにアクセスできます。
module.exports.init = function(config, logger, stats) { let emgconfigs = config.emgConfigs;
emgConfigs
に含まれるデータの例を次に示します。
{ edgemicro: { port: 8000, max_connections: 1000, config_change_poll_interval: 600, logging: { level: 'error', dir: '/var/tmp', stats_log_interval: 60, rotate_interval: 24, stack_trace: false }, plugins: { sequence: [Array] }, global: { org: 'Your Org', env: 'test' } }, headers: { 'x-forwarded-for': true, 'x-forwarded-host': true, 'x-request-id': true, 'x-response-time': true, via: true }, proxies: [ { max_connections: 1000, name: 'edgemicro_delayed', revision: '1', proxy_name: 'default', base_path: '/edgemicro_delayed', target_name: 'default', url: 'https://httpbin.org/delay/10', timeout: 0 } ], product_to_proxy: { EdgeMicroTestProduct: [ 'edgemicro-auth','edgemicro_delayed',] }, product_to_scopes: {prod4: [ 'Admin', 'Guest', 'Student' ] }, product_to_api_resource: { EdgeMicroTestProduct: [ '/*' ] }, _hash: 0, keys: { key: 'Your key', secret: 'Your key ' }, uid: 'Internally generated uuid', targets: [] }
logger
システムロガー。現在使用されているロガーはこれらの関数をエクスポートします。オブジェクトは文字列、HTTP リクエスト、HTTP レスポンス、またはエラー インスタンスです。
info(object, message)
warn(object, message)
error(object, message)
trace(object, message)
debug(object, message)
stats
リクエスト、レスポンス、エラーの数、また、Microgateway インスタンスを通過するリクエストとレスポンスに関連するその他の集計統計情報を保持するオブジェクト。
- treqErrors - エラーが発生したターゲット リクエストの数。
- treqErrors - エラーのあるターゲット レスポンスの数。
- statusCodes - レスポンス コードの数を含むオブジェクト。
{ 1: number of target responses with 1xx response codes 2: number of target responses with 2xx response codes 3: number of target responses with 3xx response codes 4: number of target responses with 4xx response codes 5: number of target responses with 5xx response codes }
- requests - リクエストの合計数。
- responses - レスポンスの合計数。
- connections - アクティブなターゲット接続の数。
next() 関数について
すべてのプラグイン メソッドで next()
を呼び出して、一連のメソッドの次のメソッドの処理を続行する必要があります(そうしないとプラグイン プロセスがハングします)。リクエストのライフサイクルで最初に呼び出されるメソッドは onrequest() です。次に呼び出されるメソッドは ondata_request()
メソッドです。ただし、ondata_request
が呼び出されるのは、POST リクエストなどのように、リクエストにデータが含まれている場合のみです。次に呼び出されるメソッドは onend_request()
です。このメソッドはリクエスト処理の完了時に呼び出されます。onerror_*
関数はエラー時にのみ呼び出されます。必要に応じてカスタムコードでエラーを処理できます。
リクエストでデータが送信され、ondata_request()
が呼び出されたとします。この関数は 2 つのパラメータで next()
を呼び出しています。
next(null, data);
慣例として、最初のパラメータはエラー情報を伝達するために使用されます。この情報は、チェーン内の後続の関数で処理できます。これを null
(誤った引数)に設定すると、エラーはなく、リクエスト処理は通常どおり続行されることになります。この引数が true(エラー オブジェクトなど)の場合、リクエスト処理が停止し、リクエストがターゲットに送信されます。
2 つ目のパラメータは、チェーン内の次の関数にリクエスト データを渡します。追加の処理を行わない場合、リクエスト データは変更されることなく API のターゲットに渡されます。ただし、このメソッド内でリクエスト データを変更し、変更されたリクエストをターゲットに渡すこともできます。たとえば、リクエスト データが XML で、ターゲットが JSON を想定している場合は、(a)リクエスト ヘッダーの Content-Type を application/json
に変更し、任意の方法を使用してリクエスト データを JSON に変換するコードを ondata_request()
メソッドに追加できます(たとえば、NPM から取得した Node.js xml2json コンバータを使用できます)。
その様子を見てみましょう。
ondata_request: function(req, res, data, next) { debug('****** plugin ondata_request'); var translated_data = parser.toJson(data); next(null, translated_data); },
この場合、リクエスト データ(XML を想定)は JSON に変換され、変換されたデータは next()
を介してリクエスト チェーンの次の関数に渡されてから、バックエンド ターゲットに渡されます。
デバッグのために、別のデバッグ ステートメントを追加して、変換後のデータを出力することもできます。次に例を示します。
ondata_request: function(req, res, data, next) { debug('****** plugin ondata_request'); var translated_data = parser.toJson(data); debug('****** plugin ondata_response: translated_json: ' + translated_json); next(null, translated_data); },
プラグイン ハンドラの実行順序について
Edge CIDR 用のプラグインを作成する場合は、プラグイン イベント ハンドラの実行順序を理解する必要があります。
注意すべき重要な点は、Edge CIDR 構成ファイルでプラグイン シーケンスを指定すると、リクエスト ハンドラは昇順で実行され、レスポンス ハンドラは降順で実行されることです。
次の例は、この実行順序を理解するのに役立ちます。
1. 3 つのシンプルなプラグインを作成する
次のプラグインを考えてみましょう。イベント ハンドラが呼び出されたときにコンソール出力を出力するだけです。
plugins/plugin-1/index.js
module.exports.init = function(config, logger, stats) { return { onrequest: function(req, res, next) { console.log('plugin-1: onrequest'); next(); }, onend_request: function(req, res, data, next) { console.log('plugin-1: onend_request'); next(null, data); }, ondata_response: function(req, res, data, next) { console.log('plugin-1: ondata_response ' + data.length); next(null, data); }, onend_response: function(req, res, data, next) { console.log('plugin-1: onend_response'); next(null, data); } }; }
次に、同じコードを使用して、さらに 2 つのプラグイン plugin-2
と plugin-3
を作成します(ただし、console.log()
ステートメントをそれぞれ plugin-2
と plugin-3
に変更します)。
2. プラグイン コードを確認する
<microgateway-root-dir>/plugins/plugin-1/index.js
にエクスポートされたプラグイン関数は、リクエストとレスポンスの処理中に特定の時間に実行されるイベント ハンドラです。たとえば、onrequest
は、リクエスト ヘッダーの最初のバイトが受信されると実行します。一方、onend_response
はレスポンス データの最後のバイトが受信された後に実行されます。
ondata_response ハンドラを見てみましょう。このハンドラは、レスポンス データのチャンクを受け取るたびに呼び出されます。レスポンス データは必ずしも一度にすべて受信されるわけではありません。むしろ、データは任意の長さのチャンクで受信できます。
3. プラグイン シーケンスにプラグインを追加する
この例で続行し、次のように、Edge CIDR 構成ファイル(~./edgemicro/config.yaml
)のプラグイン シーケンスにプラグインを追加します。順序は重要です。プラグイン ハンドラの実行順序を定義します。
plugins: dir: ../plugins sequence: - plugin-1 - plugin-2 - plugin-3
4. デバッグ出力を調べる
次に、これらのプラグインが呼び出されたときに生成される出力を見てみましょう。注意すべき重要な点がいくつかあります。
- Edge Dataprep 構成ファイル(
~./edgemicro/config.yaml
)のプラグイン順序は、イベント ハンドラが呼び出される順序を指定します。 - リクエスト ハンドラは昇順(プラグインのシーケンスに表示される順序 - 1、2、3)で呼び出されます。
- レスポンス ハンドラは降順(3、2、1)で呼び出されます。
ondata_response
ハンドラは、到着するデータチャンクごとに 1 回呼び出されます。この例では(下記の出力)、2 つのチャンクを受信します。
以下は、これら 3 つのプラグインが使用されていて、リクエストが Edge CIDR を介して送信されたときに生成されるデバッグ出力の例です。ハンドラの呼び出し順序に注意してください。
plugin-1: onrequest plugin-2: onrequest plugin-3: onrequest plugin-1: onend_request plugin-2: onend_request plugin-3: onend_request plugin-3: ondata_response 931 plugin-2: ondata_response 931 plugin-1: ondata_response 931 plugin-3: ondata_response 1808 plugin-3: onend_response plugin-2: ondata_response 1808 plugin-2: onend_response plugin-1: ondata_response 1808 plugin-1: onend_response
まとめ
リクエスト データやレスポンス データの蓄積や変換など、カスタム プラグイン機能を実装する際には、プラグイン ハンドラが呼び出される順序を理解することが非常に重要です。
リクエスト ハンドラは Edge microMicro 構成ファイルで指定されたプラグイン順に実行され、レスポンス ハンドラは逆の順序で実行されることに注意してください。
プラグインでのグローバル変数の使用について
Edge CIDR へのリクエストはすべてプラグインの同じインスタンスに送信されます。したがって、別のクライアントからの 2 番目のリクエストの状態によって、最初のリクエストが上書きされます。プラグインの状態を保存する唯一の安全な方法は、リクエスト オブジェクトまたはレスポンス オブジェクト(その存続期間はリクエストの存続期間に限定されます)のプロパティに状態を保存することです。
プラグインのターゲット URL の書き換え
v2.3.3 で追加
プラグイン コードで req.targetHostname と req.targetPath の変数を変更することで、プラグインのデフォルトのターゲット URL を動的にオーバーライドできます。
v2.4.x で追加
ターゲット エンドポイント ポートをオーバーライドして、HTTP または HTTPS を選択することもできます。プラグイン コードの req.targetPort 変数と req.targetSecure 変数を変更します。HTTPS を選択するには、req.targetSecure を true に設定します。HTTP の場合は false に設定します。req.targetSecure を true に設定する場合は、こちらのディスカッション スレッドをご覧ください。
v3.3.3 で削除
eurekaclient というサンプル プラグインは、v.3.3.3 で Edge CIDR から削除されました。リリースノートをご覧ください。
この機能が削除されても、Edge microgateway のコア機能またはターゲット URL の書き換えには影響しません。動的エンドポイント ルックアップを構成して、プラグイン レベルで req.targetHostname
、req.targetPath
、req.targetPort
、req.targetSecure
などのターゲット変数をオーバーライドできます。プラグインのターゲット URL の書き換えをご覧ください。
サンプル プラグイン
これらのプラグインは、Edge CIDR インストール環境に付属しています。これらは、Edge CIDR インストールの次の場所にあります。
[prefix]/lib/node_modules/edgemicro/plugins
ここで、[prefix]
は npm
接頭辞ディレクトリです。詳細については、Edge が表示される場所のインストールをご覧ください。
累積リクエスト
このプラグインは、クライアントからのデータチャンクを、リクエスト オブジェクトに関連付けられた配列プロパティに蓄積します。すべてのリクエスト データを受信すると、配列がバッファに連結され、次のプラグインに渡されます。蓄積されたリクエスト データを後続のプラグインが受信できるように、このプラグインは最初に配置する必要があります。
module.exports.init = function(config, logger, stats) { function accumulate(req, data) { if (!req._chunks) req._chunks = []; req._chunks.push(data); } return { ondata_request: function(req, res, data, next) { if (data && data.length > 0) accumulate(req, data); next(null, null); }, onend_request: function(req, res, data, next) { if (data && data.length > 0) accumulate(req, data); var content = null; if (req._chunks && req._chunks.length) { content = Buffer.concat(req._chunks); } delete req._chunks; next(null, content); } }; }
累積レスポンス
このプラグインは、ターゲットからのデータチャンクを、レスポンス オブジェクトに関連付けられた配列プロパティに蓄積します。すべてのレスポンス データを受信すると、配列がバッファに連結され、次のプラグインに渡されます。このプラグインは、逆の順序で処理されるレスポンスに対して動作するため、プラグイン順序の最後に配置する必要があります。
module.exports.init = function(config, logger, stats) { function accumulate(res, data) { if (!res._chunks) res._chunks = []; res._chunks.push(data); } return { ondata_response: function(req, res, data, next) { if (data && data.length > 0) accumulate(res, data); next(null, null); }, onend_response: function(req, res, data, next) { if (data && data.length > 0) accumulate(res, data); var content = Buffer.concat(res._chunks); delete res._chunks; next(null, content); } }; }
header-uppercase プラグイン
Edge CIDR ディストリビューションには、<microgateway-root-dir>/plugins/header-uppercase
というサンプル プラグインが含まれています。このサンプルには、各関数ハンドラを説明するコメントが含まれています。このサンプルでは、ターゲット レスポンスの単純なデータ変換を行い、カスタム ヘッダーをクライアント リクエストとターゲット レスポンスに追加します。
<microgateway-root-dir>/plugins/header-uppercase/index.js
のソースコードは次のとおりです。
'use strict'; var debug = require('debug')('plugin:header-uppercase'); // required module.exports.init = function(config, logger, stats) { var counter = 0; return { // indicates start of client request // request headers, url, query params, method should be available at this time // request processing stops (and a target request is not initiated) if // next is called with a truthy first argument (an instance of Error, for example) onrequest: function(req, res, next) { debug('plugin onrequest'); req.headers['x-foo-request-id'] = counter++; req.headers['x-foo-request-start'] = Date.now(); next(); }, // indicates start of target response // response headers and status code should be available at this time onresponse: function(req, res, next) { debug('plugin onresponse'); res.setHeader('x-foo-response-id', req.headers['x-foo-request-id']); res.setHeader('x-foo-response-time', Date.now() - req.headers['x-foo-request-start']); next(); }, // chunk of request body data received from client // should return (potentially) transformed data for next plugin in chain // the returned value from the last plugin in the chain is written to the target ondata_request: function(req, res, data, next) { debug('plugin ondata_request ' + data.length); var transformed = data.toString().toUpperCase(); next(null, transformed); }, // chunk of response body data received from target // should return (potentially) transformed data for next plugin in chain // the returned value from the last plugin in the chain is written to the client ondata_response: function(req, res, data, next) { debug('plugin ondata_response ' + data.length); var transformed = data.toString().toUpperCase(); next(null, transformed); }, // indicates end of client request onend_request: function(req, res, data, next) { debug('plugin onend_request'); next(null, data); }, // indicates end of target response onend_response: function(req, res, data, next) { debug('plugin onend_response'); next(null, data); }, // error receiving client request onerror_request: function(req, res, err, next) { debug('plugin onerror_request ' + err); next(); }, // error receiving target response onerror_response: function(req, res, err, next) { debug('plugin onerror_response ' + err); next(); }, // indicates client connection closed onclose_request: function(req, res, next) { debug('plugin onclose_request'); next(); }, // indicates target connection closed onclose_response: function(req, res, next) { debug('plugin onclose_response'); next(); } }; }
大文字の変換
これは一般的な変換プラグインで、必要に応じて変更して、どのような変換を行うことができます。この例では、レスポンス データとリクエスト データを単に大文字に変換します。
*/ module.exports.init = function(config, logger, stats) { // perform content transformation here // the result of the transformation must be another Buffer function transform(data) { return new Buffer(data.toString().toUpperCase()); } return { ondata_response: function(req, res, data, next) { // transform each chunk as it is received next(null, data ? transform(data) : null); }, onend_response: function(req, res, data, next) { // transform accumulated data, if any next(null, data ? transform(data) : null); }, ondata_request: function(req, res, data, next) { // transform each chunk as it is received next(null, data ? transform(data) : null); }, onend_request: function(req, res, data, next) { // transform accumulated data, if any next(null, data ? transform(data) : null); } }; }