Azure ML Web Service作成後のAPI呼び出し方法について改めて 

## Azure ML Web Service作成後のAPI呼び出し方法（Node.js） 

久しぶりにAzure Machine Learning Studioを見ていると
見慣れないリンクやAPI作成当時から若干画面が変わっている気がしたので
web Service作成後からNode.jsでの呼び出し方法まで再度まとめてみました。
リクエストのサンプルも充実していましたがnode.jsバージョンが
なかったこととレスポンスを受け取った後の処理について書かれた
ページが中々なかったため今更ですが投稿してみました。
再び必要になった際に忘れてそうなので覚書として投稿しましたが、そのため読みづらいようでしたらすみません。
また公式サイトやその他ほとんどのサイトがRequestモジュールを使用していたので折角なので新しめのライブラリで。

### 1.リクエスト
#### 1-1.ボディ
インプットとしてrequest bodyに投入すべき値は大きく分けて、

 - inputs
 - GlobalParameters
 - 
の2点となります。
inputsは投入する入力値となります。

inputsは複数の入力を受けることが可能でinput1、input2・・・等という形式で配列で持つことができます。
以下の"input1"と対応しているようです。

![Art067.jpg](https://qiita-image-store.s3.amazonaws.com/0/151893/44956668-99a6-3416-af92-c8a22bae7111.jpeg)

input1はさらにColumnNamesとValues二つのkeyを持ちColumnNamesには項目名を、Valuesには入力値を配列で指定します。同時に複数の予測を行う場合はこの配列に複数の入力のセットを設定し、一つの場合は配列の先頭のみに設定します。
またGlobalParametersはMachine Learning Studioで定義されたパラメータで以下のように作成することができますが今回は使用しませんでした。

GlobalParametersの利用方法の一例のようですが、
ML StudioのEnter Dataを選択後、右のDataのメニューからset as web service parameterを選択。
![Art058.jpg](https://qiita-image-store.s3.amazonaws.com/0/151893/67a2d797-8e85-bde6-0449-a4e9fa2115a4.jpeg)


data右側にweb serviceのマークが表示されます
![Art059.jpg](https://qiita-image-store.s3.amazonaws.com/0/151893/f6822889-6668-961e-5928-79a86d2e8f6b.jpeg)

あまり詳しいサイトが見当たらず、使用方法の一例について以下のサイトが一番詳しく記載されていました。
[Access GlobalParameters in Azure ML Python script
How can one access the global parameters ("GlobalParameters") sent from a web service in a Python script on Azure ML?](https://stackoverflow.com/questions/31838017/access-globalparameters-in-azure-ml-python-script)


結局入力値となるボディは以下のようになります。（入力値が複数の場合）


```

    let data = 
    {
      "Inputs": {
        "input1": {
          "ColumnNames": [
            "key0",
            "key1",
            "key2",
            "key3",
            "key4",
            "key5",
            "key6",
            "key7"
          ],
          "Values": [
            [
              "0",
              "0",
              "1",
              "1",
              "1",
              "1",
              "1",
              "2"
            ],[
              "1",
              "0",
              "2",
              "0",
              "1",
              "0",
              "1",
              "1"
            ]
          ]
        }
      },
      "GlobalParameters": {}
    }

``` 



#### 1-2.ヘッダ
Azure MLから取得して設定すべき項目はurlとAPIキーになります。
最初に操作する際、また久しぶりに触ると忘れているのでこれも覚書程度に。

APIキーは以下から取得します。
![Art71.jpg](https://qiita-image-store.s3.amazonaws.com/0/151893/f61e61e6-bbb3-6ff9-e76a-1d9593f5f139.jpeg)


また上記のNew Web Services Experienceリンクをたどり、APIのURLを取得するため以下のページに遷移します。

![Art062.jpg](https://qiita-image-store.s3.amazonaws.com/0/151893/81099880-c99e-e14f-4bac-e89574f6bfae.jpeg)

その後consumeタブまたはUse endpointリンクから以下の画面に遷移します。
さらに遷移先のRequest-Response > API Helpリンクをクリックします

![Art071.jpg](https://qiita-image-store.s3.amazonaws.com/0/151893/8ec09cf3-f571-b45e-5368-b083122a7547.jpeg)

遷移先の以下の画面のURIに対してリクエストします。
![Art072.jpg](https://qiita-image-store.s3.amazonaws.com/0/151893/eafe732f-c23a-1550-f4a5-590231cc6dad.jpeg)

### 2.レスポンス
#### 2-1.ボディ
レスポンスからどのように目的の予測値を取得するか記載されているサイトが少なかったので覚書です。以下のように返却されたresponseのbody内のデータから目的の予測値を取得します。最後の配列はインデックス0～7には入力値が入っておりインデックス8に目的の値が格納されています。深い・・・。

```
Results.output1.value.Values[0][8]

```

レスポンスから取得したbodyの構造は以下のようになっています。
![Art070.jpg](https://qiita-image-store.s3.amazonaws.com/0/151893/bae902f3-48e3-5fb1-170a-c2f044d7191d.jpeg)


結局呼び出し部分を抜粋すると以下のようになります。
（isomorphic-fetch使用）


```


    let fetch = require('isomorphic-fetch')
    let data = 
    {
      "Inputs": {
        "input1": {
          "ColumnNames": [
            "key0",
            "key1",
            "key2",
            "key3",
            "key4",
            "key5",
            "key6",
            "key7"
          ],
          "Values": [
            [
              "0",
              "0",
              "1",
              "1",
              "1",
              "1",
              "1",
              "2"
            ]
          ]
        }
      },
      "GlobalParameters": {}
    }
    
    const options = {
        uri: this.uri,
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            "Authorization": "Bearer " + this.apiKey,
        },
        body: JSON.stringify(data)
    }

    await fetch(this.uri, options)
    //.then((res) => res.json().Results.output1.value.Values[0][8])
    .then(function(res) {
      return res.json();
    }).then(function(json) {
        console.log(json);
    })
  }
```