勉強日記

チラ裏

JSON SchemaをYAMLで書いてYAMLを検証する


つくったもの

github.com

  • JSON Schemaのバリデータ実装としてはajvを採用
    • draft-07に対応している
  • YAML Schemaというものもあるが、fork元がdraft-04と古い

YAML Schema — ASDF Standard 1.6.0 documentation

ユースケース

  • YAMLで書かれた各種設定ファイル・仕様ファイルの規約を強制する
    • 「キー名はスネークケース」とか
    • 「なんとかatは日付または日時」とか

基本 -- オブジェクトの必須パラメータ、パラメータの型

$schema: "http://json-schema.org/draft-07/schema#"
type: object
properties:
  name:
    type: "string"
  address:
    type: "object"
    properties:
      lines:
        type: "array"
        items:
          type: "string"
      zip:
        type: "string"
      city:
        type: "string"
      country:
        type: "string"
    required:
      - "country"
  votes:
    type: "integer"
    minimum: 1
  • 検証対象データ
name: "Barack Obama"
address:
  lines:
    - "1600 Pennsylvania Avenue Northwest"
  zip: "DC 20500"
  # country: "USA"
  city: "Washington"
votes: "lots"
  • 検証
cat examples/object/input.yaml | npx ts-node index.ts -s examples/object/schema.yaml 
data/address should have required property 'country'
data/votes should be integer

応用 -- オブジェクトのキーをsnake_case強制

$schema: "http://json-schema.org/draft-07/schema#"

type: "array"
items:
  $ref: "#/definitions/snake_key_object"

definitions:
  snake_key_object:
    description: "objectのキーはsnake_caseであること"
    type: "object"
    properties: {}
    patternProperties:
      ^[a-z][a-z_]*$:
        anyOf:
          - $ref: "#/definitions/snake_key_object"
          - type: "string"
          - type: "number"
          - type: "integer"
          - type: "boolean"
          - type: "null"
    additionalProperties: false
    errorMessage: 'should have only snake_case property keys'
  • errorMessage: 'should have only snake_case property keys'フィールドは非標準
  • 入力
- foo_bar: "hoge_piyo"
  bar_baz: 123
  baz_foo: true
  foo_baz_foo: null
- {}
- topLevel: "boo"
- foo_bar: "hoge_piyo"
  nested:
    barBaz: "hogePiyo"
  • 検証
cat examples/case/input.yaml | npx ts-node index.ts -s examples/case/schema.yaml
data/2 should have only snake_case property keys
data/3/nested should have only snake_case property keys
data/3 should have only snake_case property keys

「なんとかat」に日付(Y-m-d)または日時(Y-m-d H:i:s)を強制する

$schema: "http://json-schema.org/draft-07/schema#"

type: "array"
items:
  $ref: "#/definitions/object_with_date_or_datetime"

definitions:
  date:
    description: "Y-m-d"
    type: "string"
    pattern: "^\\d{4}-\\d{2}-\\d{2}$"
  datetime:
    description: "Y-m-d H:i:s"
    type: "string"
    pattern: "^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$"
  object_with_date_or_datetime:
    properties:
      birthday:
        $ref: "#/definitions/date"
    patternProperties:
      ^[a-z_]*_at$:
        anyOf:
          - $ref: "#/definitions/date"
          - $ref: "#/definitions/datetime"
  • 入力
- created_at: "2020-01-01 00:00:00"
  birthday: "2020-01-01"
- created_at: "2020-01-01"
  birthday: "2020-01-01 12:34:56"
  • 検証
cat examples/date_or_datetime/input.yaml | npx ts-node index.ts -s examples/date_or_datetime/schema.yaml
data[1].birthday should match pattern "^\d{4}-\d{2}-\d{2}$"