概要
このポリシーを使用すると、API プロキシフローの処理中にカスタム JavaScript コードを実行できます。カスタム JavaScript コードでは、Apigee Edge JavaScript オブジェクト モデルのオブジェクト、メソッド、プロパティを使用できます。このオブジェクト モデルを使用すると、プロキシフローの処理中に変数を取得、設定、削除できます。オブジェクト モデルで提供される基本的な暗号機能を使用することもできます。
説明
JavaScript ポリシーには数多くのユースケースがあります。たとえば、フロー変数の取得と設定、カスタム ロジックの実行と障害処理の実施、リクエストやレスポンスからのデータの抽出、バックエンド ターゲット URL の動的編集などがあります。また、標準の Edge ポリシーに含まれていないカスタム動作を実装することもできます。実際に、JavaScript ポリシーを使用して、AssignMessage や ExtractVariable などの他のポリシーにより実装されるのと同じ動作を数多く実現できます。
JavaScript ポリシーでのロギングはおすすめできません。Message Logging ポリシーは、Splunk、Sumo、Loggly などのサードパーティのロギング プラットフォームへのロギングに適しています。レスポンスがクライアントに返された後に実行する PostClientFlow で Message Logging を実行することによって、API プロキシのパフォーマンスが向上します。
基本的に、JavaScript ポリシーは、実行する JavaScript ソースファイルの名前を、ポリシーが接続されているステップを実行するときに指定します。ソースファイルは常に、プロキシ バンドル内の標準の場所 apiproxy/resources/jsc
に保存されます。あるいは、ソースコードを環境レベルあるいは組織レベルのリソース ファイルに保存することもできます。手順については、リソース ファイルをご覧ください。管理 UI プロキシ エディタを介して JavaScript をアップロードすることもできます。
JavaScript ソースファイルには常に .js
拡張子が必要です。
現在サポートされている JavaScript のバージョンについては、サポートされているソフトウェアとそのバージョンをご覧ください。
動画
JavaScript ポリシーを使用してカスタム ポリシー拡張機能を作成する方法についての動画をご覧ください。
サンプル
ターゲット URL を書き直す
ここでは、リクエスト本文からデータを抽出し、それをフロー変数に保存して、そのフロー変数をプロキシフローの他の場所で使用する一般的なユースケースを紹介します。たとえば、ユーザーが HTML フォームに名前を入力して送信するアプリがあるとしましょう。そして API プロキシにフォームのデータを抽出させ、バックエンド サービスを呼び出すために使用する URL に動的に追加させるようにしたいとします。これを JavsScript ポリシーではどのように実現するでしょうか?
注: この例を試す場合は、プロキシ エディタで新しいプロキシを作成したことを前提とします。作成するときは、バックエンド サービス URL: http://www.example.com を指定してください。この例では、バックエンド URL を動的に書き直します。新しいプロキシを作成する方法がわからない場合は、スタートガイドを参照してください。
- Edge UI で、プロキシ エディタで作成したプロキシを開きます。
- [Develop] タブを選択します。
- [New] メニューから [New Script] を選択します。
- ダイアログで JavaScript を選択し、スクリプトに
js-example
などの名前を付けます。 - 以下のコードをコードエディタに貼り付けて、プロキシを保存します。重要なのは
context
オブジェクトです。このオブジェクトは、プロキシフローのどこにあっても JavaScript コードで使用できます。フロー固有の定数を取得したり、便利な get/set メソッドを呼び出したり、他にも多数の操作に使用します。このオブジェクト部分は、Edge の JavaScript オブジェクト モデルです。また、target.url
フロー変数は、ターゲット リクエスト フローでアクセス可能な組み込みの読み取り / 書き込み変数です。この変数を API URL で設定すると、Edge がこの URL に対してバックエンド呼び出しを行います。プロキシを作成したときに指定した元のターゲット URL は、基本的に書き換えています(例: http://www.example.com)。
if (context.flow=="PROXY_REQ_FLOW") { var username = context.getVariable("request.formparam.user"); context.setVariable("info.username", username); } if (context.flow=="TARGET_REQ_FLOW") { context.setVariable("request.verb", "GET"); var name = context.getVariable("info.username"); var url = "http://mocktarget.apigee.net/" context.setVariable("target.url", url + "?user=" + name); }
- [New Policy] メニューから [JavaScript] を選択します。
- ポリシーに名前を付けます(例:
target-rewrite
)。デフォルト値をそのまま使用して、ポリシーを保存します。 - Navigator で Proxy Endpoint Preflow を選択すると、ポリシーがそのフローに追加されたことが表示されます。
- Navigator で、[Target Endpoint PreFlow] アイコンを選択します。
- Navigator から、JavaScript ポリシーをフローエディタの [Target Endpoint] の [Request] 側へドラッグします。
- 保存します。
- 以下のようにして API を呼び出します。組織名とプロキシ名は正しいものに適宜置き換えてください。
curl -i -H 'Content-Type: application/x-www-form-urlencoded' -X POST -d 'user=Will' http://myorg-test.apigee.net/js-example
最後に、この例で使用した JavaScript ポリシーの XML 定義を見てみましょう。この時点で最も重要なのは、<ResourceURL>
要素は、実行する JavaScript ソースファイルを指定するために使用されることです。JavaScript ソースファイル jsc://filename.js
にも同じパターンが使用されます。JavaScript コードでインクルードが必要な場合は、このリファレンスで後述するように、1 つ以上の <IncludeURL>
要素を使用できます。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="target-rewrite"> <DisplayName>target-rewrite</DisplayName> <Properties/> <ResourceURL>jsc://js-example.js</ResourceURL> </Javascript>
JavaScript からプロパティ値を取得する
構成に <Property>
要素を追加して、ランタイムに JavaScript で要素の値を取得できます。
要素の name
属性を使用して、JavaScript コードからプロパティにアクセスするために使用する名前を指定します。<Property>
要素の値(開始タグと終了タグの間の値)は、JavaScript コードによって受け取られるリテラル値です。
JavaScript では、次のように Properties
オブジェクトのプロパティとしてアクセスするポリシーのプロパティ値を取得します。
- プロパティを構成します。ここで、プロパティ値は変数名
response.status.code
です。<Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JavascriptURLRewrite"> <DisplayName>JavascriptURLRewrite</DisplayName> <Properties> <Property name="source">response.status.code</Property> </Properties> <ResourceURL>jsc://JavascriptURLRewrite.js</ResourceURL> </Javascript>
- プロパティを JavaScript で取得します。ここで、取得された値(変数名)が
getVariable
関数で使用され、変数の値が取得されます。var responseCode = properties.source; // Returns "response.status.code" var value = context.getVariable(responseCode); // Get the value of response.status.code context.setVariable("response.header.x-target-response-code", value);
エラー処理
JavaScript コールアウトで使用できるエラー処理手法の例と説明については、Apigee コミュニティのこちらの投稿をご覧ください。Apigee コミュニティでお知らせしている提案事項は情報提供のみを目的としたものであり、必ずしも Apigee が推奨するベスト プラクティスを示しているわけではありません。
要素リファレンス
要素リファレンスは、JavaScript ポリシーの要素と属性を記述しています。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Javascript async="false" continueOnError="false" enabled="true" timeLimit="200" name="JavaScript-1"> <DisplayName>JavaScript 1</DisplayName> <Properties> <Property name="propName">propertyValue</Property> </Properties> <SSLInfo> <Enabled>trueFalse</Enabled> <ClientAuthEnabled>trueFalse</ClientAuthEnabled> <KeyStore>ref://keystoreRef</KeyStore> <KeyAlias>keyAlias</KeyAlias> <TrustStore>ref://truststoreRef</TrustStore> </SSLInfo> <IncludeURL>jsc://a-javascript-library-file</IncludeURL> <ResourceURL>jsc://my-javascript-source-file</ResourceURL> </Javascript>
<Javascript> 属性
<Javascript name="Javascript-1" enabled="true" continueOnError="false" async="false" timeLimit="200">
以下の属性は、このポリシーに固有のものです。
属性 | 説明 | デフォルト | 要否 |
---|---|---|---|
timeLimit |
スクリプトを実行する際に許容される最大時間(ミリ秒)を指定します。 注: 無料トライアル アカウントの場合、実行時間は 200 ミリ秒に制限されています。 |
なし | 必須 |
次の表に、すべてのポリシーの親要素に共通する属性を示します。
属性 | 説明 | デフォルト | 要否 |
---|---|---|---|
name |
ポリシーの内部名。 管理 UI プロキシ エディタで |
なし | 必須 |
continueOnError |
ポリシーが失敗した場合にエラーを返すには、 ポリシーが失敗した後もフローの実行を続行する場合は、 |
false | 省略可 |
enabled |
ポリシーを適用するには、 ポリシーを無効にするには、 |
true | 省略可 |
async |
この属性は非推奨となりました。 |
false | 非推奨 |
<DisplayName> 要素
管理 UI プロキシ エディタで name
属性と一緒に使用して、ポリシーのラベルに使用する自然言語名を指定します。
<DisplayName>Policy Display Name</DisplayName>
デフォルト |
なし この要素を省略した場合、ポリシーの |
---|---|
要否 | 省略可 |
タイプ | 文字列 |
<IncludeURL> 要素
<ResourceURL>
要素で指定されたメインの JavaScript ライブラリ ファイルに依存関係として読み込ませる JavaScript ファイルを指定します。このスクリプトは、ポリシーに指定した順番で評価されます。コードでは、JavaScript オブジェクト モデルのオブジェクト、メソッド、プロパティを使用できます。
複数の <IncludeURL>
要素を使用して複数の JavaScript 依存関係を含めることができます。
<IncludeURL>jsc://my-javascript-dependency.js</IncludeURL>
デフォルト: | なし |
要否: | 省略可 |
型: | 文字列 |
例
サンプル セクションの基本的な例をご覧ください。
<Property> 要素
JavaScript コードからランタイム時にアクセスできるプロパティを指定します。
<Properties> <Property name="propName">propertyValue</Property> </Properties>
デフォルト: | なし |
要否: | 省略可 |
型: | 文字列 |
属性
属性 | 説明 | デフォルト | 要否 |
---|---|---|---|
name |
プロパティの名前を指定します。 |
なし | 必須 |
例
サンプル セクションの例をご覧ください。
<ResourceURL> 要素
API フローで実行するメインの JavaScript ファイルを指定します。このファイルを API プロキシ スコープ(API プロキシ バンドルの /apiproxy/resources/jsc
の下、あるいは API プロキシ エディタのナビゲーション パネルの [スクリプト] セクション)で、あるいは組織または環境スコープで保存して、複数の API プロキシ間で再使用できます。詳しくは、リソース ファイルの説明をご覧ください。コードでは、JavaScript オブジェクト モデルのオブジェクト、メソッド、プロパティを使用できます。
<ResourceURL>jsc://my-javascript.js</ResourceURL>
デフォルト: | なし |
要否: | 必須 |
型: | 文字列 |
例
サンプル セクションの基本的な例をご覧ください。
<SSLInfo> 要素
JavaScript ポリシーにより作成されたすべての HTTP クライアント インスタンスに TLS を構成するために使用するプロパティを指定します。
<SSLInfo> <Enabled>trueFalse</Enabled> <ClientAuthEnabled>trueFalse</ClientAuthEnabled> <KeyStore>ref://keystoreRef</KeyStore> <KeyAlias>keyAlias</KeyAlias> <TrustStore>ref://truststoreRef</TrustStore> </SSLInfo>
デフォルト: | なし |
要否: | 省略可 |
型: | 文字列 |
HTTP クライアントに TLS を構成するプロセスは、TargetEndpoint/TargetServer に TLS を構成するために使用するプロセスと同じです。詳細については、Edge からバックエンドへの TLS の構成をご覧ください。
HTTP クライアントの作成の詳細については、JavaScript での HTTP クライアントの実装をご覧ください。
使用上の注意
JavaScript ポリシーに実際のコードは含まれません。その代わりに、JavaScript ポリシーは JavaScript の「リソース」を参照し、JavaScript を実行する API フローにステップを定義します。Management UI のプロキシ エディタを通じてスクリプトをアップロードするか、ローカルで開発している API プロキシの /resources/jsc
ディレクトリにスクリプトを含めることができます。
JavaScript ポリシーコードのデバッグ
print() 関数を使用して、デバッグ情報を Trace ツールのトランザクション出力パネルに出力します。詳細と例については、JavaScript の print() ステートメントを使用したデバッグをご覧ください。
print ステートメントを Trace で表示するには、次の手順を実行します。
- Trace ツールを開き、JavaScript ポリシーを含むプロキシのトレース セッションを開始します。
- プロキシを呼び出します。
- Trace ツールで、[Output from all Transactions] をクリックして出力パネルを開きます。
- print ステートメントはこのパネルに表示されます。
print() 関数を使用して、デバッグ情報を Trace ツールに出力できます。この関数は、JavaScript オブジェクト モデルで直接使用できます。詳しくは、print() ステートメントで JavaScript をデバッグするをご覧ください。
フロー変数
このポリシーは、デフォルトでは変数に何も入力しません。ただし、JavaScript コードでフロー変数を設定(および取得)できます。その場合は、コンテキスト オブジェクトでメソッドを呼び出します。一般的なパターンは以下のようになります。
context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"))
コンテキスト オブジェクトは、Apigee Edge JavaScript オブジェクト モデルの一部です。
エラー リファレンス
このセクションでは、障害コードとエラー メッセージ、障害変数について説明します。 このポリシーでエラーがトリガーされたときに Edge によって設定されます。これは、障害に対処する障害ルールを作成するうえで重要な情報です。詳細については、ポリシーエラーについて知っておくべきことと障害の処理をご覧ください。
ランタイム エラー
このエラーは、ポリシーの実行時に発生することがあります。
障害コード | HTTP ステータス | 原因 | 修正 |
---|---|---|---|
steps.javascript.ScriptExecutionFailed |
500 | JavaScript ポリシーは、さまざまな種類の ScriptExecutionFailed エラーをスローできます。よくあるエラーには、次のようなものがあります。RangeError、ReferenceError、SyntaxError、TypeError、URIError。 | build |
steps.javascript.ScriptExecutionFailedLineNumber |
500 | JavaScript コードでエラーが発生しました。詳しくは、障害文字列をご覧ください。 | なし |
steps.javascript.ScriptSecurityError |
500 | JavaScript の実行時にセキュリティ エラーが発生しました。詳しくは、障害文字列をご覧ください。 | なし |
デプロイエラー
以下のエラーは、このポリシーを含むプロキシをデプロイするときに発生することがあります。
エラー名 | 原因 | 修正 |
---|---|---|
InvalidResourceUrlFormat |
JavaScript ポリシーの <ResourceURL> または <IncludeURL> 要素で指定されたリソース URL の形式が無効な場合、API プロキシのデプロイが失敗します。 |
build |
InvalidResourceUrlReference |
<ResourceURL> または <IncludeURL> 要素が存在しない JavaScript ファイルを参照すると、API プロキシのデプロイは失敗します。参照されるソースファイルは、API プロキシ、環境、または組織レベルのいずれかに存在している必要があります。 |
build |
WrongResourceType |
このエラーは、デプロイ中に JavaScript ポリシーの <ResourceURL> 要素または <IncludeURL> 要素が jsc(JavaScript ファイル)以外のリソースタイプを参照している場合に発生します。 |
build |
NoResourceURLOrSource |
<ResourceURL> 要素を宣言していない場合、またはこの要素内にリソース URL が定義されていない場合、JavaScript ポリシーのデプロイがこのエラーで失敗する可能性があります。<ResourceURL> 要素は必須の要素です。または、<IncludeURL> 要素を宣言します。ただし、この要素内でリソース URL が定義されていません。<IncludeURL> 要素はオプションですが、宣言された場合、リソース URL を <IncludeURL> 要素内に指定する必要があります。 |
build |
障害変数
次の変数は、このポリシーでランタイム エラーが発生したときに設定されます。詳細については、ポリシーエラーについて知っておくべきことをご覧ください。
変数 | 説明 | 例 |
---|---|---|
fault.name="fault_name" |
fault_name は、上記のランタイム エラーの表に記載されている障害の名前です。障害名は、障害コードの最後の部分です。 | fault.name Matches "ScriptExecutionFailed" |
javascript.policy_name.failed |
policy_name は、障害が発生したポリシーのユーザー指定の名前です。 | javascript.JavaScript-1.failed = true |
エラー レスポンスの例
{ "fault": { "faultstring": "Execution of SetResponse failed with error: Javascript runtime error: "ReferenceError: "status" is not defined. (setresponse.js:6)\"", "detail": { "errorcode": "steps.javascript.ScriptExecutionFailed" } } }
障害ルールの例
<FaultRule name="JavaScript Policy Faults"> <Step> <Name>AM-CustomErrorResponse</Name> <Condition>(fault.name Matches "ScriptExecutionFailed") </Condition> </Step> <Condition>(javascript.JavaScript-1.failed = true) </Condition> </FaultRule>
スキーマ
各ポリシータイプは XML スキーマ(.xsd
)によって定義されます。参照用のポリシー スキーマは GitHub から入手できます。
関連トピック
- JavaScript オブジェクト モデル
- 手順、ポリシー サンプル、JavaScript サンプルについては、JavaScript を使用した API プロキシのプログラミングをご覧ください。
- Apigee Edge 用の本格的な JavaScript アプリをビルドしてデプロイする手順については、JavaScript での HTTP クライアントの実装をご覧ください。
Apigee コミュニティの記事
次の関連記事は、Apigee コミュニティでご覧いただけます。