API Connect 入力チェック 応用編

#はじめに

本記事は、[API Connect入力チェック基本編](https://qiita.com/yo24/items/05e699fa35bb4e46180a)の続編になります。

前回、API Connectの妥当性検査ポリシーを利用した、スキーマベースの入力チェック方法をご紹介しました。
具体的に紹介した入力チェック内容は、データ型や必須チェックになります。
API Connectでは、上記以外にも[OpenAPI 2.0](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md)の仕様に沿った多様な入力チェックが可能です。本誌では、そのチェック内容をご紹介します。

なお、本記事で作成したAPI定義は、[ここ](https://github.com/yo24/APIC-Validate)からダウンロードできます。

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

#数値の最大/最小
数値の最大/最小チェックを行う場合、スキーマ定義に「maximum」,[minimum]を属性を定義します。
さらに、「exclusiveMaximum」,「exclusiveMinimum」属性にtrueを付与することで、最大値、最小値と同値をエラーにすることができます。

上記属性はAPI Connectの設計タブから入力できないため、ソースタブで直接編集します(以降の属性も同様)。

```yaml
definitions:
  request-layout:
    properties:
      itemMaximum:
        type: integer
        format: int32
        description: 数値最大
        example: 10
        maximum: 15
      itemExclusiveMaximum:
        type: integer
        format: int32
        description: exclusiveMaximum
        example: 10
        maximum: 15
        exclusiveMaximum: true
      itemMinimum:
        type: integer
        format: int32
        description: 数値最小
        example: 5
        minimum: 4
      itemExclusiveMinimum:
        type: integer
        format: int32
        description: exclusiveMinimum
        example: 5
        minimum: 4
        exclusiveMinimum: true
```

```json:エラーレスポンス(maximum)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_33579:1: [JSV0009] Invalid number: 16 should be less than or equal to 15."
}
```
```json:エラーレスポンス(minimum)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_33579:1: [JSV0008] Invalid number: 3 must be greater than or equal to 4."
}
```

#文字長の最大/最小
文字数で入力チェックを行う場合、[maxLength],[minLength]属性を指定します。

```yaml
      itemMaxLength:
        type: string
        description: 文字長(最大)
        example: abcde
        maxLength: 5
      itemMinLength:
        type: string
        description: 文字長(最小)
        example: ab
        minLength: 2
```

```json:エラーレスポンス(maxLength)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_34016:1: [JSV0006] Invalid string: the string maximum length must be at most 5 (got 6)."
}
```

```json:エラーレスポンス(minLength)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_34016:1: [JSV0005] Invalid string: the minimum length must be at least 2 (got only 1)."
}
```

#正規表現
正規表現を使った入力チェックも可能です。
正規表現には、「pattern」属性を指定します。
以下の例では、半角英数カナおよびブランク以外をエラーにしています。

```yaml
      itemPattern:
        type: string
        description: 正規表現
        example: abcde
        pattern: "^([\\x01-\\x7E\\x{FF61}-\\x{FF9F}]+$)|(^$)"
```

```json:エラーレスポンス(pattern)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_33579:1: [JSV0007] Invalid string: 'abcdeあ' does not match pattern '^([\\x01-\\x7E\\x{FF61}-\\x{FF9F}]+$)|(^$)'."
}
```

なお、[pattern]属性に指定する正規表現は、プロパティーに定義することで共有することができます。

```yaml
x-ibm-configuration:
  properties:
    halfCharPattern:
      value: "^([\\x01-\\x7E\\x{FF61}-\\x{FF9F}]+$)|(^$)"
      description: ''
      encoded: false

definitions:
  request-layout:
    properties:
      itemPatternFromProp:
        type: string
        description: 正規表現(プロパティー)
        example: abcde
        pattern: $(halfCharPattern)
```

#配列長の最大/最小
配列長をチェックする場合、[maxItems],[minItems]を指定します。

```yaml
      itemMaxItems:
        type: array
        items:
          type: string
        description: 配列数(最大)
        example:
          - a
          - b
          - c
          - d
          - e
        maxItems: 5
      itemMinItems:
        type: array
        items:
          type: string
        description: 配列数(最大)
        example:
          - a
          - b
          - c
        minItems: 3
```

```json:エラーレスポンス(maxItems)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_33579:1: [JSV0004] Invalid array: the maximum number of items in the array must be at most 5."
}
```

```json:エラーレスポンス(minItems)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_33579:1: [JSV0003] Invalid array: the minimum number of items in the array must be at least 3 (got only 2)."
}
```

#配列のユニーク性
配列内容の一意性をチェックしたい場合、[uniqueItems]属性を指定します。

```yaml
      itemUniqueItems:
        type: array
        items:
          type: string
        description: 配列要素のユニーク性
        example:
          - a
          - b
          - c
        uniqueItems: true
```

```json:エラーレスポンス(uniqueItems)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_33579:1: [JSV0015] Invalid array: the array contains non-unique items."
}
```

#特定文字に限定(Enum)
コード値など特定の文字列以外を許容したくない場合は、「enum」属性を指定します。
以下の例では、red, blue, yellow以外はエラーになります。

```yaml
      itemEnum:
        type: string
        description: 値を固定
        example: red
        enum:
          - red
          - blue
          - yellow
```

```json:エラーレスポンス(enum)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_34016:1: [JSV0013] Invalid value: the value is not among the permitted enumerated values."
}
```

#倍数
数値が特定値の倍数であることをチェックしたい場合は、[itemMultipleOf]属性を指定します。

```yaml
      itemMultipleOf:
        type: integer
        description: 倍数
        example: 20
        format: int32
        multipleOf: 10
```

```json:エラーレスポンス(itemMultipleOf)
{
  "httpCode": "422",
  "httpMessage": "Invalid",
  "moreInformation": "Validate REST: xa35://tmp/temp_34016:1: [JSV0012] Invalid number: 25 is not divisible by 10."
}
```

#最後に

今回紹介した属性はAPI Connectの画面から入力できないので、気づきづらいのですが、意外と多様なチェックできることがご理解いただけたのではと思います。