メインコンテンツへスキップ
SDETRole
SDETRole

用語集 · API テスト

JSON Schema(JSON スキーマ)

英語: JSON Schema

別名: JSONスキーマ, JSON スキーマ検証, スキーマ検証, JSON Schema validation

定義

型、必須フィールド、フォーマットなど JSON データの期待される構造を記述するための JSON の語彙で、API レスポンスの検証に使われます。

JSON Schema は、有効な JSON ドキュメントがどのような形をしているかを記述する標準的な方法です。どのプロパティが存在するか、その型、どれが必須か、許可される値やフォーマットを定義します。バリデーターが実際のデータをスキーマと照合し、すべての違反を報告します。API テスターにとっては、「レスポンスは正しそうに見える」を、レスポンス全体の形を確認する 1 つの再現可能なチェックに変えてくれます。仕様の現行バージョンは draft 2020-12 ですが、draft-07 も今なお広く使われています。

具体例

GET /users/{id} が返すユーザーのスキーマです。

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "required": ["id", "email", "role", "createdAt"],
  "properties": {
    "id": { "type": "integer", "minimum": 1 },
    "email": { "type": "string", "format": "email" },
    "role": { "enum": ["admin", "member", "viewer"] },
    "createdAt": { "type": "string", "format": "date-time" },
    "nickname": { "type": ["string", "null"] }
  },
  "additionalProperties": false
}

Node で Ajv を使って検証します(ajv/dist/2020 が draft 2020-12 をサポートし、ajv-formats が email と date-time を追加します)。

import Ajv2020 from 'ajv/dist/2020';
import addFormats from 'ajv-formats';

const ajv = new Ajv2020({ allErrors: true });
addFormats(ajv);
const validate = ajv.compile(userSchema);

if (!validate(responseBody)) {
  console.log(validate.errors);
}

Java では、REST Assured の json-schema-validator モジュールが .body(...) の中で使える matchesJsonSchemaInClasspath("schemas/user.json") を提供しています。新しいキーワードを使う前に、バリデーターがどのドラフトをサポートしているかを確認してください。

なぜ重要なのか

  • 1 つのアサーションで形全体をカバーできる。 フィールドごとにチェックを書かなくても、欠けているフィールド、誤った型、予期しない null を検出できます。
  • 情報漏えいを検出できる。 "additionalProperties": false を指定すれば、レスポンスに突然 passwordHash のようなものが含まれた場合に失敗します。
  • 契約を文書化できる。 OpenAPI 仕様は、リクエストとレスポンスのボディを記述するのに JSON Schema を使っています。

よくある間違い

  • 何でも受け入れてしまうスキーマ。 required のないスキーマは {} でも合格します。必須フィールドは必ず列挙します。
  • format が強制されると思い込む。 多くのバリデーターは、フォーマット検証を有効にしない限り format を単なる注釈として扱います。
  • スキーマだけを検証する。 レスポンスがスキーマに一致していても、別のユーザーが返っている可能性があります。重要なデータについては値のアサーションも残します。

キーワードを入力すると SDETRole 全体を検索できます。

Pagefind による全文検索 · ブラウザ内で動作します 検索ページを開く →