このページは Apigee と Apigee ハイブリッドに適用されます。
Apigee Edge のドキュメントはこちらをご覧ください。
概要
このポリシーを使用すると、API プロキシフローの処理中にカスタム JavaScript コードを実行できます。カスタム JavaScript コードでは、Apigee JavaScript オブジェクト モデルのオブジェクト、メソッド、プロパティを使用できます。オブジェクト モデルを使用すると、プロキシフロー コンテキストで変数を取得、設定、削除できます。オブジェクト モデルで提供される基本的な暗号機能を使用することもできます。
このポリシーは拡張可能なポリシーです。Apigee ライセンスによっては、このポリシーの使用によって費用や使用量に影響する場合があります。ポリシータイプと使用量への影響については、ポリシータイプをご覧ください。
説明
JavaScript ポリシーには数多くのユースケースがあります。たとえば、フロー変数の取得と設定、カスタム ロジックの実行と障害処理の実施、リクエストやレスポンスからのデータの抽出、バックエンド ターゲット URL の動的編集などがあります。また、標準の Apigee ポリシーに含まれていないカスタム動作を実装することもできます。実際に、JavaScript ポリシーを使用して、AssignMessage や ExtractVariable などのポリシーで実装される多くの動作を実現できます。
JavaScript ポリシーによるロギングはおすすめしません。Splunk、Sumo、Loggly などのサードパーティのロギング プラットフォームに対するロギングには MessageLogging ポリシーのほうが適しています。レスポンスがクライアントに返された後に実行される PostClientFlow で MessageLogging ポリシーを実行することで、API プロキシのパフォーマンスを向上させることができます。
JavaScript ポリシーでは、実行する JavaScript ソースファイルを指定できます。また、<Source>
要素を使用して、ポリシーの構成に直接 JavaScript コードを組み込むことができます。いずれの場合も、ポリシーに関連付けられているステップが実行されると JavaScript コードが実行されます。ソースファイル オプションでは、ソースコードは常にプロキシ バンドル内の標準の場所(apiproxy/resources/jsc
)に格納されます。ソースコードを環境レベルまたは組織レベルのリソース ファイルに保存することもできます。手順については、リソース ファイルをご覧ください。Apigee UI プロキシ エディタから JavaScript をアップロードすることもできます。
JavaScript ソースファイルには .js
という拡張子を付ける必要があります。
Apigee では、Rhino JavaScript エンジン 1.7.13 で実行される JavaScript をサポートしています。
動画
この動画で、JavaScript ポリシーを使用してカスタム ポリシー拡張機能を作成する方法をご覧ください。
サンプル
ターゲット URL を書き直す
ここでは、リクエスト本文からデータを抽出してフロー変数に保存し、その変数をプロキシフローの他の場所で使用する一般的なユースケースを紹介します。たとえば、ユーザーが HTML フォームに名前を入力して送信するアプリについて考えてみましょう。ここで、API プロキシにフォームのデータを抽出させ、バックエンド サービスを呼び出すために使用する URL に動的に追加するとします。JavsScript ポリシーでは、これをどのように実現すればよいでしょうか。
- Apigee UI で、プロキシ エディタで作成したプロキシを開きます。
- [Develop] タブを選択します。
- [New] メニューから [New Script] を選択します。
- ダイアログで JavaScript を選択し、スクリプトに
js-example
などの名前を付けます。 - 次のコードをコードエディタに貼り付けて、プロキシを保存します。重要なのは
context
オブジェクトです。このオブジェクトは、プロキシフローのどこにあっても JavaScript コードで使用できます。フロー固有の定数の取得や、便利な get / set メソッドの呼び出しなど、この他にも多くのオペレーションに使用できます。このオブジェクト部分は、Apigee の JavaScript オブジェクト モデルです。target.url
フロー変数は、ターゲット リクエスト フローでアクセスできる組み込みの読み取り / 書き込み変数です。この変数を API URL に設定すると、Apigee はその 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 から、[Target Endpoint] の [Request] 側に JavaScript ポリシーをドラッグします。
- 保存します。
- 以下のようにして 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 コールアウトで使用できるエラー処理手法の例については、JavaScript ポリシーからエラーを返す正しい方法をご覧ください。Apigee コミュニティでお知らせしている提案事項は情報提供を目的としたものであり、必ずしも Google が推奨するベスト プラクティスではありません。
要素リファレンス
要素リファレンスでは、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> <Source>insert_js_code_here</Source> </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>
要素または <Source>
要素で指定されたメインの JavaScript ファイルに依存関係として読み込まれる JavaScript ライブラリ ファイルを指定します。スクリプトは、ポリシーに記述されている順序で評価されます。コードでは、JavaScript オブジェクト モデルのオブジェクト、メソッド、プロパティを使用できます。
複数の JavaScript 依存関係リソースを含めるには、追加の <IncludeURL>
要素を使用します。
<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 プロキシ エディタの [Navigator] ペインの [Scripts] セクション)か、組織または環境スコープに保存して、複数の API プロキシ間で再利用できます。詳しくは、リソースの管理をご覧ください。コードでは、JavaScript オブジェクト モデルのオブジェクト、メソッド、プロパティを使用できます。
<ResourceURL>jsc://my-javascript.js</ResourceURL>
デフォルト: | なし |
要否: | <ResourceURL> または <Source> が必須。<ResourceURL> と <Source> の両方が存在すると、<ResourceURL> は無視されます。 |
型: | 文字列 |
例
サンプル セクションの基本的な例をご覧ください。
<Source> 要素
ポリシーの XML 構成に直接 JavaScript を挿入できます。挿入された JavaScript コードは、ポリシーが API フローで実行された際に実行されます。
デフォルト: | なし |
要否: | <ResourceURL> または <Source> が必須。<ResourceURL> と <Source> の両方が存在すると、<ResourceURL> は無視されます。 |
型: | 文字列 |
例
<Javascript name='JS-ParseJsonHeaderFullString' timeLimit='200' > <Properties> <Property name='inboundHeaderName'>specialheader</Property> <Property name='outboundVariableName'>json_stringified</Property> </Properties> <Source> var varname = 'request.header.' + properties.inboundHeaderName + '.values.string'; var h = context.getVariable(varname); if (h) { h = JSON.parse(h); h.augmented = (new Date()).valueOf(); var v = JSON.stringify(h, null, 2) + '\n'; // further indent var r = new RegExp('^(\S*)','mg'); v= v.replace(r,' $1'); context.setVariable(properties.outboundVariableName, v); } </Source> </Javascript>
<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 を構成するプロセスと同じです。詳細については、TLS の構成オプションをご覧ください。
使用上の注意
JavaScript ポリシーコードのデバッグ
print()
関数を使用して、デバッグ情報を Debug ツールのトランザクション出力パネルに出力します。詳細と例については、JavaScript の print()
ステートメントを使用したデバッグをご覧ください。
print ステートメントを Debug で表示するには:
- Debug ツールを開き、JavaScript ポリシーを含むプロキシのトレース セッションを開始します。
- プロキシを呼び出します。
- Debug ツールで、[Output from all Transactions] をクリックして出力パネルを開きます。
- print ステートメントはこのパネルに表示されます。
print()
関数を使用して、デバッグ情報を Debug ツールに出力できます。この関数は、JavaScript オブジェクト モデルで直接使用できます。詳しくは、print() ステートメントを使用して JavaScript をデバッグするをご覧ください。
フロー変数
このポリシーは、デフォルトでは変数に何も挿入しませんが、JavaScript コードでフロー変数を設定(および取得)できます。その場合は、コンテキスト オブジェクトでメソッドを呼び出します。一般的なパターンは次のようになります。
context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"))
コンテキスト オブジェクトは Apigee JavaScript オブジェクト モデルの一部です。
エラー リファレンス
This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.
Runtime errors
These errors can occur when the policy executes.
Fault code | HTTP status | Cause | Fix |
---|---|---|---|
steps.javascript.ScriptExecutionFailed |
500 |
The JavaScript policy can throw many different types of ScriptExecutionFailed errors. Commonly
seen types of errors include
RangeError,
ReferenceError,
SyntaxError,
TypeError, and
URIError. |
build |
steps.javascript.ScriptExecutionFailedLineNumber |
500 |
An error occurred in the JavaScript code. See the fault string for details. |
N/A |
steps.javascript.ScriptSecurityError |
500 |
A security error occurred when the JavaScript executed. See the fault string for
details. |
N/A |
Deployment errors
These errors can occur when you deploy a proxy containing this policy.
Error name | Cause | Fix |
---|---|---|
InvalidResourceUrlFormat |
If the format of the resource URL specified within the <ResourceURL> or the <IncludeURL> element of the JavaScript policy is invalid, then the deployment of the API proxy fails. |
build |
InvalidResourceUrlReference |
If the <ResourceURL> or the <IncludeURL> elements
refer to a JavaScript file that does not exist, then the deployment of the API proxy fails.
The referenced source file must exist either the API proxy, environment, or organization level. |
build |
WrongResourceType |
This error occurs during deployment if the <ResourceURL> or the <IncludeURL>
elements of the JavaScript policy refer to any resource type other than jsc (JavaScript file). |
build |
NoResourceURLOrSource |
The deployment of the JavaScript policy can fail with this error if the <ResourceURL>
element is not declared or if the resource URL is not defined within this element.
<ResourceURL> element is a mandatory element. Or, The <IncludeURL> element is declared
but the resource URL is not defined within this element. The <IncludeURL> element is optional
but if declared, the resource URL must be specified within the <IncludeURL> element. |
build |
Fault variables
These variables are set when this policy triggers an error at runtime. For more information, see What you need to know about policy errors.
Variables | Where | Example |
---|---|---|
fault.name="fault_name" |
fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. | fault.name Matches "ScriptExecutionFailed" |
javascript.policy_name.failed |
policy_name is the user-specified name of the policy that threw the fault. | javascript.JavaScript-1.failed = true |
Example error response
{ "fault": { "faultstring": "Execution of SetResponse failed with error: Javascript runtime error: "ReferenceError: "status" is not defined. (setresponse.js:6)\"", "detail": { "errorcode": "steps.javascript.ScriptExecutionFailed" } } }
Example fault rule
<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 から入手できます。
関連トピック
Apigee コミュニティの記事
以下の関連記事は、Apigee コミュニティでご覧いただけます。