Azure API Management【APi Gateway】

過去、Apigeeを利用してAPi Gatewayを作成しました。

> APi Gateway Platform Apigee (1) XMLからJSONへのデータ変換
http://qiita.com/snomoto/items/3a68d5127e703505b23f

本記事においては、"Azure API Management"を利用してAPi Gatewayを作成してみようと思います。

# アカウント作成

メールアドレスとパスワードを登録すると、PINコードが送られてくるので、それをコピペしてサインアップします。
https://azure.microsoft.com/ja-jp/services/api-management/

- 基本的な、名前などの情報を入力します。
- 電話番号を登録し、改めてAuthコードをSMSで受けとり入力します。  
（基本情報で入力する電話番号は固定電話ですかね？）  
- クレジットカードを登録します。残念なことに、クレジットカードを持ってない方は使えないですね。。

# APi Managementリソースのアクティベーション

※ Azureでは様々なリソースが用意されており、それらのインスタンスを作成しアクティベーションする形で利用します。(個人的な理解

まず明らかにしておきたいのが、AzureにはAPiに関する2種類のサービスがあります。
- Azure API Management
- [Azure API Apps](https://azure.microsoft.com/en-gb/services/app-service/api/)

API Appsの方が新しくできたため、棲みわけなどについてはAPI Apps側の資料の方に詳しく書いてあります。下記のリンク先に図が書いてありますが、API AppsはAPi自体を構築するためのサービスで、すでに他のクラウド環境などでAPiを構築済みの場合は不要です。API Managementはその名の通り、APiの管理ツールであり、Gatewayを用いてAPiの統合や分析環境などを実現します。

>https://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-apps-why-best-platform#whats-the-difference-between-api-apps-and-azure-api-management

早速、Azure API Managementを利用してAPi Gatewayを作成してみましょう。

- 費用は以下。必ず、最新情報を御自身で御確認ください。  
日本円表示するならコチラ  
https://azure.microsoft.com/ja-jp/pricing/details/api-management/  

![azureqpi001a.png](https://qiita-image-store.s3.amazonaws.com/0/147747/690b1476-d85c-7f19-4612-5cd930f5f53b.png)
　　

- 公式のドキュメントが**クラシックデザインを使え**と言っているので、その通りにします。
2016年11月時点で、MSお得意のタイルデザインだとAPI Managementが(プレビュー)となっています。おそらく、新デザイン上で不具合でもあったのでしょう。クラシックデザインではプレビュー版ではありません。

> API Management を使用するにあたって最初に行うことは、サービス インスタンスの作成です。Azure クラシック ポータルにサインインし、[新規]、[App Services]、[API Management]、[作成] の順にクリックします。
https://azure.microsoft.com/ja-jp/documentation/articles/api-management-get-started/#create-service-instance

- クラシックデザインと新デザインで、微妙に選べるリージョンが違うような気がするのですが、バシバシ入力を進めていきます。
![azureapi002r2.png](https://qiita-image-store.s3.amazonaws.com/0/147747/e9a046f0-960d-4f6c-46d5-b804b30cc751.png)

- 作成時、アクティベーションにメッチャ時間がかかるので、気長に待ちましょう。。**30分くらい？？**

----
**翌日**

出来たには出来たのですが、時間のかかり方が異常です。
無料試用版でやってたからかも知れないので、ちゃんと課金した状態で利用します。

改めてクラシックポータルにサインインしようとしたところ、出来なくなっていました。ドキュメントも微妙に変わっています。
> API Management を使用するにあたって最初に行うことは、サービス インスタンスの作成です。 [Azure Portal][Azure Portal] にサインインし、[新規]、[Web + モバイル]、[API Management] の順にクリックします。
https://azure.microsoft.com/ja-jp/documentation/articles/api-management-get-started/#create-service-instance

なぜ[Azure Portal]を2回繰り返しているのでしょう。。。

- とにかく、作成します。12月になってしまいましたが、未だにプレビュー版です。  　　
<img width="512" alt="apig01.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/263f0eb9-2e59-830e-1c3b-c044877f8694.png">　　　　
　　　　

- 必要な情報を入力します。
<img width="512" alt="1dc019e3-b1b5-e8cb-1b9f-0ed0def9881d.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/4a1b123f-2bf9-eab0-175c-13ce5ac9f8c7.png">

　　
- そして待ちます。課金していれば早いでしょうか。。。
<img width="512" alt="apig03.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/5b410074-acd8-e3d1-f67f-e8c86a05a31d.png">


----
**翌日**

課金してる・してない関係ないぐらい時間かかりました。なぜ。。。
以下、無料試用版ではなく、課金可能状態であることを前提に作業します。
<img width="512" alt="apig04.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/e059ddd8-7c8e-ec37-a0b3-56627d022c84.png">


## サンプルコードを走らせてみる
用いる環境については、以下のリンク先を参考に構築してみてください。
[VMの用意(CentOS7、ApacheWebServer2.4、PHP7.1）](http://qiita.com/snomoto/items/c2793866dee81b4718e9#vmの用意)

PHPだと"http_request2"を利用するので、PEARでインストールします。

```cobolfree:termina
$sudo php71-pear install http_request2
```

開発者ポータルのページに移動します。
デフォルトで"Echo API"というAPiが存在していると思います。JSONデータであるリクエストbodyの内容を、XML形式に変換してくれます。
"Echo API"のページに各種言語でのサンプルコードがあると思います。（なんと親切な！）
更に、「Try it」の遷移先のページでは、APiの試し打ちができます。
<img width="532" alt="apig05.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/b726f438-4abc-c960-92ef-de9f420539a7.png">


- PEARを使ってhttp_request2をインストールします。
```sudo php71-pear install http_request2```

- どこか適当なフォルダに、サンプルコードをコピペし{body}と{subscription key}を書き換えて実行します。

```html:terminal
$ php71 sample.php
<Document><vehicleType>train</vehicleType><maxSpeed>125</maxSpeed><avgSpeed>90</avgSpeed><speedUnit>mph</speedUnit></Document>
```
JSONデータがXMLデータになって返って来ました。

# APi Gatewayの作成
今度は、改めてQuick Startに例示されているように、APi Gatewayをインポートしてみます。Publisher Portalを開くとすぐにインポートへのリンクがあります。
<img width="512" alt="apim001R.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/60ab58ef-df36-304c-359e-788cc461d3ff.png">

編集画面が変わっているようです。Swagger仕様のJSONファイルを読み込ませます。
<img width="512" alt="apim002.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/7a4a402c-9d76-6200-c10c-13376272f602.png">

作成したら、「Products」から、作成したcalcのAPiを「Starter」に割り当てます。
<img width="512" alt="スクリーンショット 2016-12-05 4.03.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/efea1737-9590-dfdb-31ef-63453acd4176.png">

<img width="512" alt="1977c52b-2f71-9161-51ea-8a3d33247270.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/c91aa33a-e0a1-ce70-4b1c-f9e739fe45c0.png">


「Starter」への紐つけが完了すると、Developer Portalの方にも反映されます。
<img width="512" alt="apim006.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/967ac24b-598c-2536-3937-9bdca3fa060e.png">

単純な、四則演算を実装したAPiが無事にインポートされました。
<img width="882" alt="スクリーンショット 2016-12-05 3.54.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/8d564ff4-595e-c4c0-584b-4663147e6698.png">



# アクセス制限をかける
*ココカラ2016年12月5日追記*

- 何もしてない状態のEcho Apiを叩いてみる

```html:terminal
$php71 echo.php 

<Document><vehicleType>train</vehicleType><maxSpeed>125</maxSpeed><avgSpeed>90</avgSpeed><speedUnit>mph</speedUnit></Document>
```

## IPアドレスを利用したアクセス制限
「Policies」から、設定します。下図の上から順に設定してみてください。矢印の"CONFIGURE POLICY"をクリックすると、XMLを編集出来ます。
<img width="512" alt="ipwhite001.png" src="https://qiita-image-store.s3.amazonaws.com/0/147747/29cd85ca-33e7-4de7-24ec-eebe78130769.png">

- 特定のIPアドレスからだけ、アクセスを許容する。という設定を書き込みます。
レンジで範囲指定したい場合は、"from" "to"の行を利用してください。

```xml:sampleXML
<policies>
	<inbound>
		<base />
		<ip-filter action="allow">
			<address>指定するIPアドレスを入力</address>
		</ip-filter>
		<json-to-xml apply="always" consider-accept-header="false" />
	</inbound>
	<backend>
		<base />
	</backend>
	<outbound>
		<base />
	</outbound>
</policies>
```

これを「Save」で保存するだけです。
サーバからアクセス出来ることを確認したら、Developer Portalの方で「アクセスできないこと」を確認してみましょう。IPアドレスが許容されていないので、アクセス出来なくなっているはずです。
![ipwhite002.png](https://qiita-image-store.s3.amazonaws.com/0/147747/eca9e455-3fde-5921-d523-fce29f3597b2.png)

先ほどまではアクセス出来ていたのに、"403 Forbidden"に変わりました。
IPアドレスを利用したアクセス制限が出来ました。
別のサーバからも叩いてみます。

```cobolfree:terminal
$ php71 echo.php 
{ "statusCode": 403, "message": "Forbidden" }
```
大丈夫そうです。

# おわりに
ApigeeのようにGatewayに機能を追加するには、Publisher Portalの「Policies」から操作すれば良さそうです。
やはりBasic認証については、Apigeeと同じく御助け機能的な感じで、裏側にアクセスする際に上手くユーザ／パスワードを効かせてくれるものでした。そもそも、もうBasic認証なんて使わないで！という。。