JavaScript ポリシー

概要

このポリシーを使用すると、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 を動的に書き直します。新しいプロキシを作成する方法がわからない場合は、スタートガイドを参照してください。

  1. Edge UI で、プロキシ エディタで作成したプロキシを開きます。
  2. [Develop] タブを選択します。
  3. [New] メニューから [New Script] を選択します。
  4. ダイアログで JavaScript を選択し、スクリプトに js-example などの名前を付けます。
  5. 以下のコードをコードエディタに貼り付けて、プロキシを保存します。重要なのは 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);
    }
    
  6. [New Policy] メニューから [JavaScript] を選択します。
  7. ポリシーに名前を付けます(例: target-rewrite)。デフォルト値をそのまま使用して、ポリシーを保存します。
  8. Navigator で Proxy Endpoint Preflow を選択すると、ポリシーがそのフローに追加されたことが表示されます。
  9. Navigator で、[Target Endpoint PreFlow] アイコンを選択します。
  10. Navigator から、JavaScript ポリシーをフローエディタの [Target Endpoint] の [Request] 側へドラッグします。
  11. 保存します。
  12. 以下のようにして 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

ポリシーの内部名。name 属性の値には、英字、数字、スペース、ハイフン、アンダースコア、ピリオドを使用できます。この値は 255 文字を超えることはできません。

管理 UI プロキシ エディタで <DisplayName> 要素を追加して、ポリシーのラベルに使用する別の自然言語名を指定することもできます。

なし 必須
continueOnError

ポリシーが失敗したときにエラーを返す場合は、false に設定します。これは、ほとんどのポリシーで想定される動作です。

ポリシーが失敗した後もフローの実行を続行する場合は、true に設定します。

false 任意
enabled

ポリシーを適用するには、true に設定します。

ポリシーを無効にするには、false に設定します。ポリシーがフローに接続されている場合でも適用されません。

true 任意
async

この属性は非推奨となりました。

false 非推奨

<DisplayName> 要素

管理 UI プロキシ エディタで name 属性と一緒に使用して、ポリシーのラベルに使用する自然言語名を指定します。

<DisplayName>Policy Display Name</DisplayName>
デフォルト

なし

この要素を省略した場合、ポリシーの name 属性の値が使用されます。

要否 任意
種類 文字列

<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 で表示するには、次の手順を実行します。

  1. Trace ツールを開き、JavaScript ポリシーを含むプロキシのトレース セッションを開始します。
  2. プロキシを呼び出します。
  3. Trace ツールで、[Output from all Transactions] をクリックして出力パネルを開きます。

  4. 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 エラーをスローできます。よくあるエラーには、次のようなものがあります。RangeErrorReferenceErrorSyntaxErrorTypeErrorURIError
steps.javascript.ScriptExecutionFailedLineNumber 500 JavaScript コードでエラーが発生しました。詳しくは、障害文字列をご覧ください。 なし
steps.javascript.ScriptSecurityError 500 JavaScript の実行時にセキュリティ エラーが発生しました。詳しくは、障害文字列をご覧ください。 なし

デプロイエラー

以下のエラーは、このポリシーを含むプロキシをデプロイするときに発生することがあります。

エラー名 原因 解決方法
InvalidResourceUrlFormat JavaScript ポリシーの <ResourceURL> または <IncludeURL> 要素で指定されたリソース URL の形式が無効な場合、API プロキシのデプロイが失敗します。
InvalidResourceUrlReference <ResourceURL> または <IncludeURL> 要素が存在しない JavaScript ファイルを参照すると、API プロキシのデプロイは失敗します。参照先のソースファイルが API プロキシ、環境、組織レベルのいずれかに存在している必要があります。
WrongResourceType このエラーは、デプロイ中に JavaScript ポリシーの <ResourceURL> 要素または <IncludeURL> 要素が jsc(JavaScript ファイル)以外のリソースタイプを参照している場合に発生します。
NoResourceURLOrSource <ResourceURL> 要素を宣言していない場合、またはこの要素内にリソース URL が定義されていない場合、JavaScript ポリシーのデプロイがこのエラーで失敗する可能性があります。<ResourceURL> 要素は必須の要素です。または、<IncludeURL> 要素を宣言します。ただし、この要素内でリソース URL が定義されていません。<IncludeURL> 要素はオプションですが、宣言された場合、リソース URL を <IncludeURL> 要素内に指定する必要があります。

障害変数

次の変数は、このポリシーでランタイム エラーが発生したときに設定されます。詳細については、ポリシーエラーについて知っておくべきことをご覧ください。

変数 説明
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 コミュニティでご覧いただけます。