APIConnect 入力チェック-基本編

# はじめ
IBM API Connectでは、事前定義したスキーマベースの入力チェックが可能です。
しかし、マニュアル等には具体的にどのようなチェックが可能なのかは明記されていません。

そこで今回は、この入力チェック機能の基本的な使い方をご紹介します。

なお、今回作成するAPI定義は、以下からダウンロードできます。
https://github.com/yo24/APIC-Validate

# 環境

IBM CloudのAPI Connectサービス(2019年6月時点)を利用します。

# スキーマ定義

API Connectの入力チェックを行うためには、スキーマ定義が必要です。
まずは、設計タブの「定義」で、スキーマを定義します。

まずは定義を新規追加します。名前は下図の通りとしていますが、任意でOKです。
![def-layout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/474e560d-5256-7cfa-599a-6c893548f2ac.png)

次に、プロパティーを追加し、スキーマ内の項目を定義します。
本記事では、以下のように定義してみました。
![def-layout-item.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/a050b369-41ff-a708-91f0-97b268162ca9.png)

+ 左端は必須項目を定義します
+ 「タイプ」で設定可能な値は、[OpenAPI 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types "OpenAPI 2.0") の仕様に準拠します
+ 「例」は、APIの動作には関係ありませんが、開発者ポータルでの表示やアセンブルのテスト機能のテストデータ生成に利用されます(後述)

# パス

次に、先ほど作成したスキーマ定義を、APIのメソッド+パスに紐付けます。
まずは、パスの定義から行います。
今回は、パスに「/」、メソッドに「POST」を設定しています。
![path1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/7b78cc6f-7c94-f249-3a0d-435ee4c0eef9.png)

次に、メソッド(例ではPOST)を選択し、パラメーターを追加します。
今回、JSONデータを送信したいので、場所は「本文(分かりづらいですがHTTP Bodyと思えばOK)」、タイプに先の手順で追加したスキーマ定義を指定します。
![path-layout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/99ef63c2-ef92-43e9-795c-b285abb47eea.png)


# アセンブル

次に、アセンブル(API動作)を定義します。
妥当性検査ポリシーを配置し、ポリシーの「定義」で、先に作成したスキーマ定義を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/4d107934-1f12-45f1-8761-d78542c5c01d.png)


# 動作確認

アセンブルのテスト機能を有効にします(操作方法が分からない場合は[ここ](https://qiita.com/yo24/items/d2493e87f1ccc496f2dd#%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D)を参照してください)。
次に、操作(POST /)を選択すると、リクエストデータの入力項目が現れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/a19c0b45-49e0-a9a9-a23c-1191a1265095.png)

ここで、生成を選択すると、スキーマ定義で入力した「例」に沿って、データを生成してくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/44ab55a4-8ccc-cb52-859d-3a8577fc94cc.png)

ひとまず、この状態でAPIを実行してみましょう。
データは正しいので、HTTPステータスコード=200で応答されます。
レスポンスは、アセンブルで何も処理していないので、送信データがそのまま設定されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/53ad7aa2-2294-ba4e-b333-e0bf7a936417.png)

次に、入力チェックエラーになるようにリクエストデータを修正してみます。
itemStrを数値に修正してみました。

```json:request
{
  "itemStr": 100,
  "itemInt": 10,
  "itemBool": true,
  "itemDate": "2019-06-09",
  "itemDateTime": "2019-06-09T08:00:00.000+09:00"
}
```

APIを実行すると、入力チェックエラーとなり、以下のデータがレスポンスされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135384/20da6161-56f8-a146-2443-a122e96856f4.png)

+ HTTPステータスコード 422 Unprocessable Entityは、サーバーが要求本文のコンテンツ型を理解でき、要求本文の構文が正しいものの、中に含まれている指示が処理できなかったことを表します


# 一通り試してみた

先に定義したスキーマ定義で、一通り入力チェックエラーをおこし、結果をまとめたものが下表です。
なお、入力チェックはエラー対象が１項目でもあれば、それ以降のチェックはスキップされます(全項目、まとめて実行するわけではない)。

| エラー | httpCode | httpMessage | moreInformation |
|:--|:--|:--|:--|
| JSON構文不正  | ４００ | Bad Request | Invalid JSON payload received.  |
| Valueを未設定(Keyのみ) | ４００ | Bad Request | The body of the request, which was expected to be JSON, was invalid, and could not be decoded. A valid property value was not found.  |
| 数値として解釈不可な値(ex.000) | ４００ | Bad Request | The body of the request, which was expected to be JSON, was invalid, and could not be decoded. The number syntax was invalid.  |
| stringに数値  | ４２２ | Invalid | Validate REST: xa35://tmp/temp_321935:1: [JSV0001] Invalid value type 'integer |
| Integerに文字  | 422  | Invalid | Validate REST: xa35://tmp/temp_321935:1: [JSV0001] Invalid value type 'string'.  |
| Booleanに文字 | 422  | Invalid | Validate REST: xa35://tmp/temp_321935:1: [JSV0001] Invalid value type 'string'.  |
| Date型に不正な日付 | 422  | Invalid | Validate REST: xa35://tmp/temp_321935:1: [JSV0007] Invalid string: '2019-06-32' does not match pattern '^[0-9]{4}-[0-1][0-9]-([0-2][0-9]|3[0-1])$'.  |
| DateTimeに不正な日時 | 422  | Invalid | Validate REST: xa35://tmp/temp_321935:1: [JSV0007] Invalid string: '2019-06-09T08:00:00.000+0' does not match pattern '^[0-9]{4}-[0-1][0-9]-([0-2][0-9]|3[0-1])(T|t|\\s)([0-1][0-9]|2[0-3]):[0-5][0-9]:([0-5][0-9]|60)([.][0-9]*)?(Z|z|(([+]|-)([0-1][0-9]|2[0-3]):[0-5][0-9]))?$'. |
| 必須エラー | ４２２ | Invalid | Validate REST: xa35://tmp/temp_321935:1: [JSV0002] Invalid object: the property 'itemStr' is missing. |

# 最後に

今回は、API Connectで入力チェックを実現する方法をご紹介しました。
簡単に実装できる反面、入力チェック内容が限られていたり、エラーメッセージがいまいちだったりするのが残念ですね。

上記のいまいち感をカバーすべく、次回以降、他の入力チェックを実現する方法、エラーメッセージを上書きする方法を紹介したいと思います。