API Connect v2018 ゲートウェイ・タイプでのコンテキスト変数操作の記述差異

#はじめに

API Connect v2018では、異なる2種類のゲートウェイ・タイプが提供されています。
V5と互換性のあるV5互換モードと、新しく提供されるAPIGWモードです。

[Knowledge Center: API Connect のゲートウェイ・タイプ](https://www.ibm.com/support/knowledgecenter/ja/SSMNED_2018/com.ibm.apic.overview.doc/rapic_gateway_types.html)


V5互換モードで開発していたAPI定義を、APIGWモードで動作させるにはAPI定義のソース変換が必要になります。具体的な方法は以下のリンク先を参照してください。

[Knowledge Center: Converting an API definition for deployment to the DataPower API Gateway](https://www.ibm.com/support/knowledgecenter/en/SSMNED_2018/com.ibm.apic.toolkit.doc/tapic_api_convert.html)

また、上記で記載されている内容に加え、GatewayScriptの内容について、コンテキスト変数の記述方法で注意が必要となります。ここでは、それぞれのゲートウェイ・タイプでのGatewayScriptの記述方法の違いについてまとめます。


# コンテキスト変数操作の違い

V5で使用してきたapimモジュールは、V2018（v5c）モードでは引き続き使用できます。
しかし、V2018（APIGW）モードでは、明示的に読み込まないと使用できなくなっています。

[Knowledge Center: GatewayScript code examples](https://www.ibm.com/support/knowledgecenter/en/SSMNED_2018/com.ibm.apic.toolkit.doc/rapim_gwscript_codesnip.html)

ただし、apimモジュールを使用する場合は、APIGWモードでのパフォーマンスを最大限に活かすことができない可能性があるため注意が必要です。

[stackoverflow: Api Connect GatewayScript, apim is not defined](https://stackoverflow.com/questions/53727406/api-connect-gatewayscript-apim-is-not-defined)


APIGWモードでは、新たに提供されているcontextオブジェクトや、そのメソッドを利用することができます。

[Knowledge Center: Using context variables in GatewayScript and XSLT policies with the DataPower API Gateway](https://www.ibm.com/support/knowledgecenter/en/SSMNED_2018/com.ibm.apic.toolkit.doc/rapic_apigw_apis_gws_xslt.html)

以下では、apimオブジェクトで操作したコンテキスト変数の操作を、新たなcontextオブジェクトでどのように実施できるか比較して紹介します。

## 取得

- v5互換では、「apim.getvariable」や、「apim.getContext」を使用
- APIGWでは、「context.get」などを使用

| 対象データ          | v5互換           | APIGW    |
|:-----------------|:-----------------------|:------------------------|
| HTTPボディー | apim.getvariable('message.body')| context.get('message.body') <br> or <br> context.message.body.readAsJSON|
| HTTPヘッダー | apim.getvariable('message.headers.**_Variable_**')| context.message.header.get('**_Variable_**') |
| HTTP結果 | apim.getContext('message.status.code')| context.message.statusCode |
| その他コンテキスト変数 |apim.getContext('client.app.id') | context.get('client.app.id') |
| Swagger文書 |apim.getContext(api.document)	| context.swagger.readAsJSON |

HTTPボディーや、Swagger文書については、「xxx.readAsJSON」という方法で非同期で取得されます。
この場合、データの取り込みが完了する前に次の処理に進むので注意が必要です（ただし、次のポリシーには進まない）。データの取り込みが終了した段階で、function内の処理が実施されます。


     //message.bodyの非同期読み込み。読み込みが完了したら、jsonに代入されてfunction内の処理を開始
     context.message.body.readAsJSON(function(error, json) {              
 
         ～message.bodyの編集処理～
         
         //再度message.bodyに書き込む
         context.message.body.write(json);
     });




## 設定・クリア

| 対象データ          | v5互換           | APIGW    |
|:-----------------|:-----------------------|:------------------------|
| HTTPボディー | apim.setvariable('message.body', '**_Variable_**')| context.message.body.write('**_Variable_**')|
| HTTPヘッダー設定・クリア | apim.setvariable('message.headers.**_Variable_**','**_Value_**') <br> or <br>apim.setvariable('message.headers.**_Variable_**','',clear)| context.message.header.set('**_Variable_**','**_Value_**') <br>or<br> context.message.header.remove('**_Variable_**') |
| その他コンテキスト変数設定・クリア | apim.setvariable('**_Variable_**','**_Value_**') <br> or<br> apim.setvariable('**_Variable_**','',clear)| context.set('**_Variable_**','**_Value_**') <br>or<br> context.clear('**_Variable_**') |

## その他
| その他操作          | v5互換           | APIGW    |
|:-----------------|:-----------------------|:------------------------|
| 例外処理 | apim.error('**_ErrorName_**')| context.reject('**_ErrorName_**','**_ErrorMessage_**')|


# 最後に
この記事ではAPIGWモードでのGatewayScriptの記述方法について、V5互換モードと比較する形で紹介しました。V5互換で開発したAPI定義をAPIGWモードに変換する際の参考にしていただければと思います。