このページは Apigee と Apigee ハイブリッドに適用されます。
Apigee Edge のドキュメントを表示する。
JavaScript ポリシーを使用すると、API プロキシフローのコンテキストで実行されるカスタム JavaScript コードを追加できます。このポリシーを使用すると、Apigee ポリシーでカバーされていないカスタム動作を実装できます。
カスタム JavaScript コードでは、Apigee JavaScript オブジェクト モデルのオブジェクト、メソッド、プロパティを使用できます。プロキシ フロー コンテキストで変数の取得、設定、削除、カスタム ロジックの実行、障害処理の実施、リクエストやレスポンスからのデータの抽出、バックエンド ターゲット URL の動的編集を行うことができます。オブジェクト モデルで使用できる基本的な暗号機能を使用することもできます。
JavaScript ポリシーでは、実行する JavaScript ソースファイルを指定できます。また、<Source> 要素を使用して、ポリシーの構成に直接 JavaScript コードを組み込むことができます。いずれの場合も、ポリシーが関連付けられているステップが実行されると JavaScript コードが実行されます。
ソースファイル オプションでは、ソースコードは常にプロキシ バンドル内の標準の場所(apiproxy/resources/jsc)に格納されます。ソースコードを環境レベルまたは組織レベルのリソース ファイルに保存することもできます。手順については、リソース ファイルをご覧ください。Apigee UI プロキシ エディタを使用して JavaScript をアップロードすることもできます。
Apigee では、次の目的で JavaScript ポリシーを使用することをおすすめしません。
- Logging。MessageLogging ポリシーは、Splunk、Sumo、Loggly などのサードパーティのロギング プラットフォームでのロギングに適しています。このポリシーは、レスポンスがクライアントに返された後に PostClientFlow で実行されるため、API プロキシのパフォーマンスも向上させます。
- Apigee ポリシーの置き換え。JavaScript ポリシーは、Apigee ポリシーの機能を置き換えるものではありません。必要な機能が Apigee ポリシーで利用可能な場合は、カスタム JavaScript ソリューションを実装する代わりに、そのポリシーを使用します。カスタム JavaScript コードは、Apigee ポリシーのパフォーマンスと最適化に匹敵しない可能性があります。
JavaScript ソースファイルには .js という拡張子を付ける必要があります。
Apigee では、Rhino JavaScript エンジン 1.7.13 で実行される JavaScript をサポートしています。
このポリシーは拡張可能なポリシーであり、Apigee ライセンスによっては、このポリシーの使用によって費用や使用量に影響する場合があります。ポリシータイプと使用量への影響については、ポリシータイプをご覧ください。
サンプル
ターゲット URL を書き直す
一般的なユースケースでは、リクエスト本文からデータを抽出し、フロー変数に保存して、そのフロー変数をプロキシフローの他の場所で使用します。たとえば、ユーザーが HTML フォームに名前を入力して送信するとします。フォームのデータを抽出してバックエンド サービスの URL に動的に追加するには、JavaScript ポリシーを使用します。
- Apigee UI で、プロキシ エディタで作成したプロキシを開きます。
- [Develop] タブを選択します。
- [New] メニューから [New Script] を選択します。
- ダイアログで JavaScript を選択し、スクリプトに
js-exampleという名前を付けます。 - 次のコードをコードエディタに貼り付けて、プロキシを保存します。
contextオブジェクトは、プロキシフローのどこにあっても JavaScript コードで使用できます。フロー固有の定数を取得したり、便利なget/setメソッドを呼び出したり、その他のオペレーションを実行したりします。このオブジェクトは、Apigee JavaScript オブジェクト モデルの一部です。target.urlフロー変数は、ターゲット リクエスト フローでアクセスできる組み込みの読み取り/書き込み変数です。この変数を API URL に設定すると、Apigee はそのバックエンド URL を呼び出します。これにより、元のターゲット 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という名前を付けます。デフォルト値をそのまま使用して、ポリシーを保存します。 - [ナビゲータ] で [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> 属性
< languageVersion="VERSION_1_3" Javascript name="Javascript-1" enabled="true" continueOnError="false" async="false" timeLimit="200">
| 属性 | 説明 | デフォルト | 要否 |
|---|---|---|---|
| languageVersion |
コードが記述されている JavaScript 言語のバージョンを指定します。値には、 |
VERSION_DEFAULT | 省略可 |
| 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 ツールのトランザクション出力パネルに出力します。詳細と例については、print() ステートメントでの JavaScript のデバッグをご覧ください。
Debug ツールで print ステートメントを表示するには:
- Debug ツールを開き、JavaScript ポリシーを含むプロキシのトレース セッションを開始します。
- プロキシを呼び出します。
- デバッグツールで、[Output from all Transactions] をクリックして出力パネルを開きます。
![Apigee Trace ツールの [Output from all Transactions] パネルに、print ステートメントが表示されている。](https://docs.cloud.google.com/static/apigee/docs/api-platform/images/output-transactions.png?authuser=6&hl=ja)
- print ステートメントはこのパネルに表示されます。
フロー変数
このポリシーは、デフォルトでは変数に何も挿入しません。ただし、context オブジェクトでメソッドを呼び出すことで、JavaScript コードでフロー変数を設定して取得できます。次に例を示します。
context.setVariable("response.header.X-Apigee-Target", context.getVariable("target.name"))
context オブジェクトは、Apigee JavaScript オブジェクト モデルの一部です。
エラー リファレンス
このセクションでは、このポリシーによってエラーがトリガーされたときに返される障害コードとエラー メッセージ、および Apigee によって設定される障害変数について説明します。これは、障害に対処する障害ルールを作成するうえで重要な情報です。詳細については、ポリシーエラーについて知っておくべきことと障害の処理をご覧ください。
ランタイム エラー
このエラーは、ポリシーの実行時に発生することがあります。
| 障害コード | 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 から入手できます。
関連トピック
Apigee コミュニティの記事
以下の関連記事は、Apigee コミュニティでご覧いただけます。