APIGatewayのHTTP ProxyでKintoneのREST APIを呼ぶ（１）

Amazon APIGatewayのHTTP Proxyを使ってKintoneのREST APIを呼び出してみます。
Kintoneを呼び出すための環境依存情報は外部から注入できるようにします。

こちらの記事を参考にしました。
[外部サイトから直接kintone APIを実行したい](http://qiita.com/ha_ru_ma_ki/items/ccb7c535d8ef1b255365)

__注意__
__kintone REST APIは同時アクセス数がドメインごとに10と制限されています。__

> ドメインへの同時アクセス
> 　・APIによる同時アクセス数はドメインごとに10が上限です。
>
> [REST APIの共通仕様](https://cybozudev.zendesk.com/hc/ja/articles/201941754-REST-API%E3%81%AE%E5%85%B1%E9%80%9A%E4%BB%95%E6%A7%98#step12)

実システムで利用する場合は、API Gatewayのスロットリング設定やエラーのリトライなどを考慮する必要が有ります。

注意ここまで

# 必要なもの

* Kintoneのアカウント（Developerでも大丈夫です。Developerではない場合、APIを使用するのでスタンダードコースが必要です）
* AWSのアカウント

# 実現すること

* クライアント（Webブラウザ）から以下のBodyを持つPOSTリクエストを送信するとKintoneにデータが入る

```json
{
    "item1":"fuga","日本語項目":"ほげ"
}
```

* クライアントにはKintoneに関する情報（APITokenなど）は開示しない
* Kintoneから返されたエラーをクライアントで判定する

# Kintoneのアプリの準備

以下の項目を持つアプリを作成します。

* フィールドコード：item1
 * フィールド名：項目１
 * 必須入力にする
* フィールドコード：日本語項目
 * フィールド名：日本語項目

このアプリでAPIトークンを生成します。
![image](https://qiita-image-store.s3.amazonaws.com/0/117772/abb22498-8ac8-e7bf-04fc-c82096ee3d16.png)
今回は登録のみなのでPOSTの権限だけあればOKです。

Kintoneから必要な情報は、以下のとおりです。
* サブドメイン（Kintoneを利用するときのURL xxxxxx.cybozu.com のxxxxxxです)
* アプリのID
* APIトークン

先に言っておきますと、Kintoneのフィールドコードが日本語の場合、ちょっぴり問題がある可能性があるので、英数字で定義しておいたほうが良いです。

# APIGateway

## APIを定義

今日からConsoleが結構変わったのよね、、、

![image](https://qiita-image-store.s3.amazonaws.com/0/117772/b96a78fe-9af0-8f84-680a-8fc98b53fbbd.png)

POSTメソッドを追加し、以下のように設定します。
![image](https://qiita-image-store.s3.amazonaws.com/0/117772/4fed7faf-ba68-615c-9aef-232ccbc50a7e.png)

Endpoint URL：` https://${stageVariables.subdomain}.cybozu.com/k/v1/record.json` の`${stageVariables.subdomain}`が後ほど定義するStageVariablesへの参照です。

## KintoneへのリクエストヘッダにAPIトークンを渡す

Integration RequestでHttpヘッダの設定をします。

![image](https://qiita-image-store.s3.amazonaws.com/0/117772/29bca8b8-09e1-1873-3389-ae9f84b3d19b.png)

## クライアントのリクエストをKintoneのリクエストにマッピングする

KintoneのPOSTリクエストのBodyは以下の仕様になっています。

```json
{
    "app": "(アプリのID)",
    "record": {
        "(フィールドコード)": {
            "value": "(フィールド値)"
        }
    }
}
```

引用：[cybozu.com developer network/kintone API/REST API (レコード)/レコードの登録（POST）](https://cybozudev.zendesk.com/hc/ja/articles/202166160-%E3%83%AC%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AE%E7%99%BB%E9%8C%B2-POST-)

この「アプリのID」と「フィールド値」をMappingTemplateを使って設定します。

![image](https://qiita-image-store.s3.amazonaws.com/0/117772/1ee3c1dc-41ef-11c4-de73-ecf9c2bf8c9b.png)

Content-Type:application/jsonのリクエストに対するBodyを以下のように入力します。

```javascript
{
    "app":"${stageVariables.app}",
    "record":{
        "item1":{"value":$input.json('$.item1')},
        "日本語項目":{"value":$input.json('$.日本語項目')}
    }
}
```

* `${stageVariables.app}`はStageから取得する変数です。
* `$input.json('$.item1')`は、JSON形式のリクエストボディからitem1というプロパティを取得する書き方です。（see [API Gatewayのマッピングテンプレートリファレンス](https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html)）

これを入力したら右下のSaveボタンをクリックすると反映されるのですが、入力した日本語は"?"に化けてしまいます。
![image](https://qiita-image-store.s3.amazonaws.com/0/117772/1bf1e880-96f7-2406-2e62-42c0bc1d8b89.png)
しかしながら、CLIで取得すると、日本語のまま定義されていますし、このまま進んでも正常に動作しています。

とはいえ、気持ち悪いのでKintoneでの日本語フィールドコードは使用しないほうが無難かと思います。

## 動作テスト

ここまでで簡単に動作確認してみます。Method Testのページ（稲妻マーク）を開きます。

![image](https://qiita-image-store.s3.amazonaws.com/0/117772/85d022c3-3107-d4a6-4286-4c2cc0ca584f.png)

このようにStageVariablesが入力可能になっているはずです。もし出てきていなければページをリロードしてみてください。

StageVariablesにKintoneで定義した時の値を入力して、まずはRequestBodyを空のままで送信してみましょう。

![image](https://qiita-image-store.s3.amazonaws.com/0/117772/f0261e25-8d91-2dcd-f469-0eba5a8397d3.png)

このようにメッセージが文字化けしています（orz）。が、Kintoneにリクエストが送信されていることは間違いなさそうです。

リクエストヘッダに何かを設定することで英語のメッセージをKintoneが返してくれたような気がするのですが、ManagementConsole上の問題だけなので、とりあえず良しとします。
ちなみに化けていなければ、このような内容です。

```json
{
  "message": "入力内容が正しくありません。",
  "id": "1505999166-328617945",
  "errors": {
    "record.item1.value": {
      "messages": [
        "必須です。"
      ]
    }
  },
  "code": "CB_VA01"
}
```

では、正しいRequestBodyを設定してみます。

```json
{"item1":"data","日本語項目":"日本語入力"}
```

![image](https://qiita-image-store.s3.amazonaws.com/0/117772/6cdd886d-71e0-f0da-1677-c347ab87ef39.png)

無事にKintoneに入りました！

後はDeployして、、、と行きたいところなのですが、このままでは不都合があります。
先ほど、RequestBodyを空で送信した際に、Kintoneからはエラーが返ってきているにもかかわらず、APIGatewayはHTTP ステータスコード２００を返してしまっています。

なので、次回はエラーハンドリングを入れて、以下のことを行います。

* Kintoneからのエラーをエラーとして返す
* DeployしてStageVariablesを定義する
* 呼ぶ