関連
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "ほげほげ",
  "type": "object",
  "properties": {},
  "required": []
}

$schema

これには今現在(2019-04)最新のhttp://json-schema.org/draft-07/schema#バージョンを指定します。

title

そのスキーマの説明。

type

ルートに置かれるtypeは、その JSON のルートがどんな要素かを指定します。objectarrayが指定できます。

properties

type:objectな時、どんなプロパティがあるかを指定していきます。例えば以下は、fooプロパティが置けるという意味になります。

{
  "properties": {
    "foo": {
      "description": "説明(オプション)",
      "type": "string"
    }
  }
}

この各プロパティのタイプには

  • string

  • number

  • object

  • array

  • boolean

  • null があります。

required

type:objectな時、ここに羅列したプロパティは必ず設定しなければならないという意味になります。以下はfooを必須にする例です。

{
  "properties": {"foo": {}},
  "required": ["foo"]
}

key: &keyのようにキーの横に&block-nameと書くとそのブロックをそれ以降で使い回せるようになります。これは場所はどこでもいいです。以下のbar,quux,piyoはどれも有効です。

foo:
  bar: &bar
    value: value
  baz:
    qux:
      quux: &quux
        value: value
    hoge:
      fuga:
        piyo: &piyo

オブジェクトに埋め込む

commonという共通ブロックを設定しました。

common: &common
  one: one
  two: two

このように<<: *block-nameという記法で使えます。

foo:
  zero: zero
  <<: *common
  three: three

これは JSON にするとこのような感じです。fooブロックの中に共通ブロックのonetwoを入れれました。

{
  "foo": {
    "zero": "zero", 
    "one": "one",
    "two": "two",
    "three": "three"
  }, 
  "common": {
    "two": "two", 
    "one": "one"
  }
}

配列に埋め込む

配列の場合は- *block-nameという記法で埋め込みます。commonは同じものを使います。また例です。

foo:
  - zero: zero
  - *common
  - three:
      value: value

JSON にするとこのような感じです。onetwoというキーを持ったオブジェクトがちゃんと入っているのが分かります。

{
  "foo": [
    {
      "zero": "zero"
    }, 
    {
      "one": "one"
      "two": "two", 
    }, 
    {
      "three": {
        "value": "value"
      }
    }
  ], 
  "common": {
    "two": "two", 
    "one": "one"
  }
}
関連

typestringを指定したものは、文字列のプロパティ値を期待する事になります。ただ文字列という情報だけでは範囲が広すぎる場合、それを狭める為のオプションもいくつか用意されています。

デフォルト値

defaultを使うと初期値を設定できます。

{
  "type": "string",
  "default": "foo"
}

特定のワードに限定

これは別にstringだけのオプションではないですが、enumオプションがあります。type:stringの場合、これは文字列の配列を指定できます。以下に例を置きます。

{
  "type": "string",
  "enum": [
    "foo",
    "bar",
    "baz"
  ]
}

この設定で上のプロパティはfoobar, bazのどれかを置いてほしいという意味になります。

ここでexamplesというオプションも似たような動作になります。ただし、enumは「必ずどれかを置く」というのを期待しますがexamplesの場合は、単に「例えばこういうのが置けますよ」と提示するだけです。

{
  "type": "string",
  "examples": [
    "foo",
    "bar",
    "baz"
  ]
}

文字列の長さの制限

minLengthmaxLengthオプションが用意されています。どちらも設定するのは数値で、minLengthの数値以上maxLengthの数値以下の文字列に絞り込むことができます。

{
  "type": "string",
  "minLength": 2,
  "maxLength": 5
}

この設定はabcは正しい、abcdefは間違いだと判断されます。

文字列のパターンで制限

例えば URL を期待している箇所に適当な文字列を置かれても困るので、 URL のパターンを設定することでそれにマッチしない場合は誤りであることを伝えることができます。これにはpatternオプションが用意されています。pattern内では\wなどの\\\とエスケープする必要があります。
いくつか一派的なパターンはformatで定義できます。これにはemailuriなどがあります。

またpatternformatは組み合わせて使えます。formatは若干甘いパターンなので、formatが用意されているものは積極的に使い、patternで強固にするのが良いと思います。

以下にいくつか絞る例を上げてみます。

Email

{
  "type": "string",
  "format": "email"
}

exampleは駄目でexample@email.comは通ります。もしgmail.comだけに絞りたい場合は以下のようになります。

{
  "type": "string",
  "format": "email",
  "pattern": ".*@gmail.com"
}

URI

https://のようなプロトコルが部分が含まれていれば大丈夫な場合"format": "uri"が用意されてます。

{
  "type": "string",
  "format": "uri"
}

これだとプロトコル名の部分が何でも通るのでpatternと組み合わせてhttpswssかと絞ることができます。

{
  "description": "url",
  "type": "string",
  "format": "url",
  "pattern": "^(https|wss)://"
}

パス部分のパターンを厳しくしたりも可能です。

{
  "type": "string",
  "format": "url"
  "pattern": "^(http(s)?://)?[\\w.-]+(?:\\.[\\w\\.-]+)+[\\w\\-\\._~:/?#[\\]@!\\$&'\\(\\)\\*\\+,;=.]+$"
}

DateTime

IOS8601(RFC3339) 形式(2020-04-21T04:01:43.730077309Z2020-04-21T04:01:43.730077309+09:00のような文字列)で絞れます。

{
  "type": "string",
  "format": "date-time"
}

同じような感じでdatetimeというformatもあり、これらはそれぞれTの前、Tの後だけになったものです。

Color

残念ながら色にはformatが用意されてません。ただ以下のようにすることで#fff#000000のような文字列に絞ることはできます。

{
  "type": "string",
  "pattern": "^#([0-9a-fA-F]{3}){1,2}$"
}
関連

type:numberと設定することで数値を期待しているという意味にできます。そして数値にもさらに期待値を絞り込むようなオプションがいくつかあります。

ある数値の倍数だけに制限

multipleOf:<number><number>の倍数だけを期待しているという意味にできます。以下は3の倍数だけを期待するという意味になります。

{
  "type": "number",
  "multipleOf": 3
}

範囲

  • 以上

  • 大きい

  • 以下

  • 小さい

数値を期待するという意味にできるオプションがあります。ちょっと順番が変わります。

以上

minimumを置きます。

{
  "type": "number",
  "minimum": 10
}

これは、「最小値はこれ以上にしてくださいね」という感じです。

大きい

minimumに合わせてexclusiveMinimum:falseを設定すると、「最小値は除外で」という意味にできます。

{
  "type": "number",
  "minimum": 10,
  "exclusiveMinimum": true
}

これは、11からの数値を期待します。

以下

maximumを置きます。

{
  "type": "number",
  "maximum": 40
}

これは、「最大値はこれ以下にしてくださいね」という感じです。

小さい

maximumに合わせてexclusiveMaximum:falseを設定すると、「最大値は除外で」という意味にできます。

{
  "type": "number",
  "maximum": 40,
  "exclusiveMaximum": true
}

これは、39以下の数値を期待します。

組み合わせ

もちろんこれらは組み合わせて使えます。以下は10 <= num <= 40な数値を期待する例です。

{
  "type": "number",
  "minimum": 10,
  "maximum": 40,
}

特定の数値のどれか

数値でもenumを使うことで、特定の数値のどれかを期待するという意味にできます。以下は3111002を期待するという意味になります。

{
  "type": "number",
  "enum": [
    3,
    11,
    1002
  ]
}
関連

type:booleanを置くとtruefalseを期待するという意味になります。

デフォルト値

defaultオプションを置くと、VScodeなどではプロパティ名を確定した時点でこの値も置かれるようになります。

{
  "type": "boolean",
  "default": false
}

type:objectを置くとオブジェクトを期待するという意味になります。期待するプロパティやその値を絞り込むオプションがいくつかあります。

特定のプロパティ時の期待値の設定

propertiesを置き、その中でそれぞれのプロパティ名とその名前の時のスキーマを設定できます。

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string"
    },
    "bar": {
      "type": "number"
    },
  }
}

これは以下のような意味になります。

  • まず、オブジェクトです

  • そのオブジェクトがfooを持つならそれは文字列です

  • そのオブジェクトがbarを持つならそれは文字列です

  • そのオブジェクトがbazを持つならそれは型は何でもいいです

なので以下は通ります。

{
  "foo": "foo",
  "baz": false
}

厳密なプロパティ

additionalProperties:falsepropertiesと共に置くことで、完全にproperitesのプロパティ構造以外のプロパティは禁止されるようになります。つまり、先程は設定できたbazは駄目になるという事です。

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string"
    },
    "bar": {
      "type": "number"
    },
  },
  "additionalProperties": false
}

やや厳しく

additionalProperties:<設定>propertiesに置いていないプロパティの期待する型を絞ることができます。例えば以下はfooプロパティ以外の値はnumberを期待するスキーマの例です。

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string"
    },
  },
  "additionalProperties": {
    "type": "number"
  }
}

絶対定義してほしいプロパティ

reuiqred:<properties>propertiesと共に置くとここで羅列したプロパティ名は必須項目という意味になります。例えば以下は「fooは絶対に定義してね」という意味になります。

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string"
    },
    "bar": {
      "type": "number"
    },
  },
  "required": [
    "foo"
  ]
}

依存関係のプロパティ

先程から何度か「reuiqred:<properties>propertiesと共に置くと...」のように言っていますが、このように「requiredpropertiesが存在するなら設定できる」ような関係を設定できるオプションがあります。

これはdependenciesを置きます。これはこのプロパティは: [これらのプロパティに依存する]というような感じで置きます。

例えば以下はbarを置くなら必ずfooを定義しなければならないというスキーマの例です。

{
  "type": "object",
  "properties": {
    "foo": {
      "type": "string"
    },
    "bar": {
      "type": "number"
    },
  },
  "dependencies": {
    "bar": ["foo"]
  }
}

プロパティ名のパターン

propertyNames: {pattern:<pattern>}を置くとプロパティ名はそのパターンにマッチするものだけ期待するという意味にできます。以下はcolor.orangecolor.blueなどcolor.からはじまるプロパティだけを期待する例です。

{
  "type": "object",
  "propertyNames": {
   "pattern": "^color\\."
  }
}

プロパティの数

minProperties:<number>maxProperties:<number>を置くことでそれぞれ、「これ以上はプロパティ数を置いてほしい」、「これ以下にプロパティ数を抑えてほしい」という意味にできます。

{
  "type": "object",
  "minProperties": 2,
  "maxProperties": 3
}
関連

type:arrayとすることで何らかの構造の配列を期待するという意味になります。そして、何らかのと書いたように中身をある程度絞り込むようなオプションがいくつかあります。

構成アイテムの型を設定

items:<定義>プロパティで設定できます。例えば以下のような書き方で「数値の配列」という意味にできます。

{
  "type": "array",
  "items": {
    "type": "number"
  }
}

いくつかの型が混じっている

例えばnumberfalseが混ざったものを期待したい場合はanyOfというものを使います。これは「どれかに当てはまってればいいよ」というような構造にすることができるオプションです。

{
  "type": "array",
  "items": {
    "anyOf": [
      {
        "type": "number",
      },
      {
        "type": "boolean",
        "enum": [false]
      }
    ]
  }
}

タプル

itemsの中を配列にすることでタプルにできます。

{
  "type": "array",
  "items": [
    {
      "type": "string"
    },
    {
      "type": "number"
    }
  ]
}

これは以下のようなものを期待します。

[
  "foo",
  123,
  false,
  null
]

見て分かる通り先頭が期待した通りならあとは何でもいいという感じになってます。もし、期待した通りのタプルにしたいならadditionalItems:falseを一緒に置きます。

{
  "type": "array",
  "items": [
    {
      "type": "string"
    },
    {
      "type": "number"
    }
  ],
  "additionalItems": false
}
[
  "foo",
  123
]

ちなみにadditionalItemsに文字列などを設定すると、定義以降の部分の型をそれに絞ることができます。

{
  "type": "array",
  "items": [
    {
      "type": "string"
    },
    {
      "type": "number"
    }
  ],
  "additionalItems": {
    "type": "string"
  }
}
[
  "foo",
  123,
  "bar",
  "baz"
]

ユニークな値

重複した値は欲しくない時があるかもしれません。そんな時はuniquness:trueを共に置きます。

{
  "type": "array",
  "uniquness": true
}

これで以下のような定義は駄目になります。

[
  "foo",
  "foo"
]

配列のサイズ

minItemsmaxItemsを使います。それぞれ、最小の配列サイズと最大の配列サイズを設定できます。

{
  "type": "array",
  "minItems": 2,
  "maxItems": 3
}
関連

type:nullと設定することでnull値を期待できます。

このこの型については特に説明はありません。

複雑な型というのは

  • 複数の条件すべてにマッチしなければならない

  • どれかにマッチすればいい(ホワイトリスト)

  • 複数の条件のうち1つにマッチしなければならない

  • マッチしてはならない(ブラックリスト)

などがあります。

複数の条件すべてにマッチしなければならない

これにはallOfを使います。

{
  "allOf": [
    {
      "type": "string"
    },
    {
      "pattern": "\w+"
    }
  ]
}

別れているので少しややこしいですが、以下のようにするのと同じ意味です。

{
  "type": "string",
  "pattern": "\w+"
}

主に#refな条件を組み合わせる為に使ったりします。

どれかにマッチすればいい(ホワイトリスト)

これにはanyOfを使います。「ここではstringnumberを置いてほしい」という要望なら、以下のようになります。

{
  "anyOf": [
    {
      "type": "string"
    },
    {
      "type": "number"
    }
  ]
}

複数の条件のうち1つにマッチしなければならない

これにはoneOfを使います。例えば以下のようなスキーマだったとします。

{
  "oneOf": [
    {
      "type": "string"
      "pattern": "^a"
    },
    {
      "type": "string"
      "pattern": "z$"
    }
  ]
}

ここにはaazzは置くことができますが、azは両方にマッチしてしまうので置くことができません。

マッチしてはならない(ブラックリスト)

これにはnotを使います。例えば以下のようにすると「booleanobjectarray, null以外を期待する(stringnumber)」という意味になります。

{
  "not": [
    {
      "type": "boolean"
    },
    {
      "type": "object"
    },
    {
      "type": "array"
    },
    {
      "type": "null"
    },
  ]
}

ローカルのsettings.jsonjson.schemasという項目を置きます。

settings.json を作る

VSCode はプロジェクトルートに置かれているvscode/settings.jsonファイルを自動で読み込み、設定に適用してくれるので、とりあえずこれを以下のような内容で作ります。

{
  "json.schemas": []
}

この配列は、

type Schema =
  | {fileMatch: string[], url: string}
  | {fileMatch: string[], schema: object}

なオブジェクトで構成された配列になります。

fileMatch

fileMatchは文字列な配列で、その JSON スキーマを適用するファイルのパターンやパスを置きます。今回のようなローカルのsettings.jsonの場合は/はプロジェクトルートになります。

[
  {
    "fileMatch": [
      "/foo/**/xxx.json",
      "/absolute/aaa/xxx.json
    ],
  }
]

url

スキーマファイルへのパスまたは URL を置きます。このパスの場合も、ローカルのsettings.jsonの場合は/はプロジェクトルートになりますので、/.../.../xxx.jsonのように絶対パスで指定します。
URL の場合は、JSON スキーマを提供している URL を設定します。例えば、npm のpackage.jsonのスキーマであれば、http://json.schemastore.org/packageという URL を置くと良いです。

[
  {
    "fileMatch": ["**/*"],
    "url": "http://json.schemastore.org/package"
  }
]

schema

これはurlプロパティを設定しない時に必要です。単に JSON スキーマをこのオブジェクトの中に記述していきます。

[
  {
    "fileMatch": ["**/*"],
    "schema": {
      "type": "object"
    }
  }
]

関連エラー

Request vscode/content failed unexpectedly without providing any details.(768)

自身のものを使う時はどこか参照できる URL などに置くと思いますが、その URL が302リダイレクトなどしている場合上のメッセージのように読み込んでくれません。これはリダイレクト先の URL を記述することによって直ります。

僕の場合怒ったのは、npm に公開してunpkg.comから取得しようとした時です。https://unpkg.com/nju33/xxx/foo.jsonという URL はhttps://unpkg.com/nju33/xxx@0.0.0/foo.jsonのような URL へリダイレクトする設定となっていた為です。

ちょっと不便ですね,,,

JavaScript で飯食べたい歴約 9 年、 純( nju33 ) によるノートサイトです。

このサイトではドリンク代や奨学金返済の為、広告などを貼らせて頂いてますがご了承ください。

Change Log