API Connect でコンテキスト変数にアクセスしてみた

# API Connect コンテキスト変数とは

IBM API Connectのコンテキスト変数は、APIの呼び出しに関連する変数で、その内容はリクエストのメッセージに関連する情報やシステム情報などです。
API Connectでは、アセンブルの処理で必要に応じてこのコンテキスト変数を参照することができ、メッセージ処理においてこれらのコンテキスト変数の値を利用することができます。


# API Connect コンテキスト変数の一覧
API Connectで利用できる利用できるコンテキスト変数の一覧は、API ConnectのKnowledge Centerに記述されています。
[API Connectのコンテキスト変数](https://www.ibm.com/support/knowledgecenter/ja/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/rapim_context_var.html)

# API Connect コンテキスト変数の参照方法

コンテキスト変数は、GatewayScriptポリシーやMAPポリシーで参照できます。

## JavaScript/GatewayScriptポリシーで参照する場合
アセンブリのGatewayScriptで参照する場合は、以下のメソッドを使用します。
###参照時
apim.getvariable('ContextVariable')
###設定時
apim.setvariable('ContextVariable', Value, Action)

##インライン参照
マップや、Proxy/InvokeポリシーのURLフィールドで参照する場合
$('ContextVariable')

詳細は、Knowledge Centerをご参照ください
[API Connectでの変数参照](https://www.ibm.com/support/knowledgecenter/ja/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/capim_context_references.html)

# API Connect コンテキスト変数の参照例
コンテキスト変数で参照したデータをそのまま応答電文として戻すAPIを実装してみます。
API Connectでは、アセンブルで何も記述しない状態でAPIを公開すると、正常応答"200 OK"を戻すシンプルなAPIが実装できます。
GatewayScriptポリシーを使用して、コンテキスト変数を参照してそれを含む応答電文を戻すことができます。

# GatewayScriptポリシーでの記述
GatewayScriptポリシーを配置して、以下のコードを記述します。
以下の例は、requestコンテキスト全体を参照して、メッセージのボディにそのままセットしています。

\# コンテキスト変数(request.path)を参照する例
var request_path = apim.getvariable('request.path'); 

\# requestコンテキストを参照する例
var request_context = apim.getvariable('request'); 
\# requestコンテキストをメッセージ・ボディにセットする例
apim.setvariable('message.body',request_context);

アセンブリ上でProxy/Invokeポリシーを配置しない場合、折り返し処理となり、message.bodyの内容が応答電文として戻されます。

# API ConnectでのAPI定義の例
API Connect for Bluemixの環境があれば、新規にAPIを作成して、以下のような実装を行います。

|項目         |値                |
|:------------|:----------------|
| 基本パス    |/contextapi       |
| パス        |/request         |
| メソッド    |GET            |
|　　　　　　　|POST         |

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193979/190b5560-8b49-0ab3-e657-b7144d31a579.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193979/b6821171-1ba5-6dde-4385-5488ba1d6a7b.png)

このようなAPIを作成してそのままアセンブルの画面で、GatewayScriptポリシーを配置して、以下の処理を記述します。


var context_request = apim.getvariable('request');
apim.setvariable('message.body',context_request);

![image.png](https://qiita-image-store.s3.amazonaws.com/0/193979/b1b15d01-aed5-9088-6cbb-b21484836f76.png)


アセンブル画面の上部の三角形のアイコンをクリックすると、そのままこのAPIを含む製品をステージング、公開してテストすることができます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193979/c8e07c89-e188-5bd8-de31-e2a2376cf90b.png)


<img src="https://qiita-image-store.s3.amazonaws.com/0/193979/4e50896c-0927-d5e0-92f6-0cb48777e752.png" width="250">

<img src="https://qiita-image-store.s3.amazonaws.com/0/193979/d8f19f0d-d107-568c-81a1-e511433367d5.png" width="250">
(中略)
<img src="https://qiita-image-store.s3.amazonaws.com/0/193979/ae445849-6887-aa99-690f-597d2e346118.png" width="250">


このステージング、公開の情報を参照して、curlコマンドによる外部からのAPI呼び出しもできます。
###コマンド実行例
##GET時
$ curl -u admin:password 'https://api.au.apiconnect.ibmcloud.com/xxxxx-apic/sb/contextapi/request?parm1=1&parm2=2' -H 'accept: application/json' -H 'x-ibm-client-id: ed23282c-95c9-4a24-b25b-67580bea2d46'

###requestコンテキストの内容
{
	"verb": "GET",
	"uri": "https://168.1.31.173:443/xxxxx-apic/sb/contextapi/request?parm1=1&parm2=2",
	"path": "/contextapi/request",
	"headers": {
		"host": "api.au.apiconnect.ibmcloud.com",
		"authorization": "Basic YWRtaW46cGFzc3dvcmQ=",
		"user-agent": "curl/7.55.1",
		"accept": "application/json",
		"via": "1.1 AQAAAJcLuRo-",
		"x-client-ip": "168.1.17.11",
		"x-global-transaction-id": "61078277"
	},
	"date": "Wed, 25 Oct 2017 07:17:27 Z",
	"authorization": "Basic YWRtaW46cGFzc3dvcmQ=",
	"querystring": "parm1=1&parm2=2",
	"search": "?parm1=1&parm2=2",
	"parameters": {
		"parm1": "1",
		"parm2": "2"
	}
}

APIリクエストのURLパスやパラメータ、ヘッダー、おおよそのリクエスト受付時間などがコンテキスト変数で参照できます。


##POST時
$ curl -u admin:password -X POST 'https://api.au.apiconnect.ibmcloud.com/xxxxx-apic/sb/contextapi/request' -H 'accept: application/json' -H 'Content-Type: application/json' -H 'x-ibm-client-id: ed23282c-95c9-4a24-b25b-67580bea2d46' -d '{"field1":"date1","field2":"date2","field3":3}'

###requestコンテキストの内容
{
	"verb": "POST",
	"uri": "https://168.1.31.189:443/xxxxx-apic/sb/contextapi/request",
	"path": "/contextapi/request",
	"headers": {
		"host": "api.au.apiconnect.ibmcloud.com",
		"authorization": "Basic YWRtaW46cGFzc3dvcmQ=",
		"user-agent": "curl/7.55.1",
		"accept": "application/json",
		"content-type": "application/json",
		"content-length": "46",
		"via": "1.1 AAAAACFdhP8-",
		"x-client-ip": "168.1.17.11",
		"x-global-transaction-id": "27135545"
	},
	"content-type": "application/json",
	"body": "{ \"field1\":\"date1\", \"field2\":\"date2\", \"field3\":3 }",
	"date": "Wed, 25 Oct 2017 07:22:45 Z",
	"authorization": "Basic YWRtaW46cGFzc3dvcmQ=",
	"querystring": "",
	"search": " ",
	"parameters": ""
}


コンテキスト変数の内容を参照するためのサンプル例のため、ヘッダー等の考慮はしていませんのでご了承ください。
上記出力例は、IBM Bluemix上のAPI Connectに公開したAPIを呼び出した場合の例です。
異なるバージョンやオンプレ環境での利用においては、必要に応じて出力結果をご確認ください。