JSONスキーマのJSONスキーマを作って簡易作成フォームにしてしまう [jdorn/json-editor]

JSONスキーマに触れた誰もが考えそうなネタですが、json-editorでビビっときた人は是非。

> **JSON schema とは**
> その名の通りですがJSONの形式を定義するJSONです。XMLで言うWSDLの様なもの（余計わかりづらい？）

> **jdorn/json-editorとは**
> JSON schema と拡張定義を用いてJSONの入力フォームを作ることができる仕組みです。


※jdorn/json-editorのJSONスキーマに最適化したJSONスキーマです。JSONスキーマのスキーマなら本家にあるよ・・JSONスキーマと仕様違うよね・・というツッコミは返答に困ってしまいますのでご遠慮ください。

また、oneOf、allOf等、取り込めていない仕様や入力規則がありますが、ちょっとしたフォーム作成・簡単なAPIインターフェース定義はとりあえず作れます。（改善歓迎）

JSONスキーマ作成フォーム
[https://rawseq.github.io/json-editor-sb/](https://rawseq.github.io/json-editor-sb/#schema=N4KABBYEQC4JYwDYFMoC5oCkDKB5AcoJ0MgtQyA-DIHsMgOvKAIRmABQBWAJgPYBOAdgPQMDOLHALTImCdgEooAGnCQoTZLwDGbOAAd4A9NAA8AQzAALNsgBmAXgDkhmDDW80XLgHMEhgK4AjAHRKWAWx5WTh5+IRExNksAPhs7BydXGA8fP0Dmdm4+AWFRGHYdLj1onU82EoNjMys4+0cuNj0Ad15kAEdvJJTvOBZQnIj8tkFeTy5LMBg9NmdkGCsAfU9EPQ4AaxjahIbm1o6urx6+7PC89hGxwuLS8sBn5UAoOUAYBkBQDMA7t0BYBkAdhkB+hkBnhkBzBkAejqAcgNAEkMgF-4wAFSoB1BkAfgyATQZAEAM0lkECgABITKZtFAAMRcBSmOAcBC9Di8LhqNgsNTINgwACeKMg0EJxNJAl42lALJZUCpNLpjO5qN5fIUylUGjJOJBgFGDQCMGoAsf4egDsGF4fH4AkFvUGAdI1ANh2-0AsgwI5EyMVi2AM2k4lieBjIJQwZmWvkC2n0uCKEVut2wBAoX1+kMBpCoDBQb6AEoZABMMgGuGV0h-2M22R3gwVQcZxQUXJsAAXwt+bkqYjYB5Jat8HDOMAdF6APQyk1XSzby1AM1mc8WW3JkBx3P5tABtPO9uSd4ndsfj6DEmDIWZsZuztED-yeOkr1dQaaNJk91do+2O53b2dQTwsFgoVbn8dQAeIRC5o8AXUPvagNM05ODR7RftBwWGsUC5DBRwAy0oEAcNNAHVtQB0JToSds0kT8oOgQAXU0AB1M6HnRc6TQmcAKgbDABIFOh103NgiIw3koEAWUSkL3PQGVoui5DeOgTydGB2I46BAHx3QBfBTIsAABU2HcZAuAAMT0RBWjoK8b2QVZ+I4x93GfV8MLfYj8wLAzLSLYyrVMdh-D0F0MErC9QPbQAjfUAeH173za002gFDpyPKAgKHCCzJLWBkAADxddD7LCqYTD0NyWy0jct0ih9kCsuAXxSr93DYTKgvchc8ro+RrNQLKEqYUr4H8ZBBEQFglAU+KqxKhdqrK-LkygfwBGSZrgqaZBkDWfqCrgGrRq6xpsw64q-Hq5dypa5xVCYSbQyUQwnTWK9QvWv1YD0ZZZowjtkBQM8luC3g2iK069GdMlJXUCLOtDTxrM2okgyu9ylH2-0lDUNQAegvxTFMIbQatJReEMaYQd+rrYa5JHQ0q+lofopgGFWZwWCxvlkD4Qm+1yvHSbRfGVmzSnoBW68ADcDzeg74Y4JgUA+thUdZ-14d4NZzruqCoHh0KTtFmx-BFkj2TpqBcYUBXccZuK0YO1W9GejQVbCBWwN54rEDgXhEb56DEHcdWLatKyhe+yWSKstg1lYJoOAVqykCOr2GRu2XfJ4x7GadBW1G1xrA53T1o4vNRnAD8PDHN4q1AZZItA1-1Ftt+ipM8Fnit4bWjdO5QFJt4uUYV3gXeFbPoKTxurQzBkrbL0XeEZnzTpgJo4F70XGc8HXXuK0KZYVhk9CnvP9N7Uyv0JPRtJsis8489tvKxsMg0jQB4yMALO0yN0qsl4S-z-wfBycUADwTADyjQAigN3sscRYoudwQNLwI34rb8jI-J+gBmhlIIASYYFZv3TJmKcZ9xxGUXhrfk1JPTwB9LZTeUDoDB3HjuAB0AuI4O8B6IU3peAaWXooFQL0ZSRjVBqL4fxADSDIASIZQFgMALAqoJACmioAbKVoSADMGKEgjADyDIAAwZACqDIAEQZzSbwjrYOkHAAAKKDSHoL-qdbwAAqa+xVMRmBxPiNkJJfwUhIfSJkecWQINXDY8+SD5ELk4CowUXp1F2Rvm2O0DpeKv0DO2QAiwzfFIL8QhPjnTEOsk45Rqi3HkN3hKah0otB0PuOqN4jDfisMAMbWB9AAWEYAP+cgkhJ4fwoRMIBHiOkbI3yjjFEuNQWQ3RO5tHNNFvo7EkYjFmHZKYyksThRWMgHY+BrML4tW-v4X+HivwdMMQSHpJinr9NcQ3TB-icRMUAIGRgACXzoB-HoC4pmSDGUg2KrAOCICZBg3yWCoD4SXH42skZAC1UYAfwZABryoAKIZABAOoACldd5X0CnRAADC3XkABGee4LvzJL-Dc06-kQL+N-pBAS0ApFSMABIMdM+SAHsGKRcD3x5xGYZJBP4nptOCvgqAgBnKMAAy+gBaKKPq-LxkYcG7wsmwb2OIVpwDWjC8xaDplDLRPNFY9gRBUtuRsyMgAMoy+YAZ1dADJDGIwAbU6AGlDQA1gzwkANEMuLWyeUvNeW8ntwX+gpZyaVp0+VMAWPNQc8KwAACZRW8lJbY81chRAl2OgsD+-qmBrQRQJPe7YmKqihIAQkdACdSgatEdyVKmvjdguFIr0X0Vtfam8jrf6uozR62c4ySI+qOigf1bB9wLAUCgBc1r7KyugBGwAUkqABM02NKat44iTWpM1bq+SWqdTM9FUAs0Ov8E6-N6LC3wK9WiUtfqA0mHYAoZcIbNI0ojYAMjlACeDIAf7MsUdrnfRRNJre2dsHemjNcgx05onXm-twy3XFt8gu8t4q9CSvrTfRtUAFWKreUex9Ca2XQB7XeY9A603ft8req297tBToEjOxBbr5CmzLcgBYgwFgnBgwlGlOACCAAvfQAY2lAYzV2yM4G+2Ucvfhi8cHc2IeA4WZ9x70O+vLUKpp67-6-reGRijI7T2qQg6x2FpiGMPiYwhjASGOIoZbC+ncHAWCBryGSBSCwePuIkzSt40a42QcNe2GjF7oN8ZHbJydrGlP2LQ4YflChPZWdFjSwABWnwk7aJ5NJnjyWY0de+mq1s3wdswW9jaGbNXtDTSx4tr3guUAODGR9ABCZqqQA1QyAEuGQABwyAFE9VLdAIWCAhc6ihfdQP3I4AuR5UXipIocrFjdv6gExgTIACH-HhAPYe8QAFgxbsAM4MoJAAQKoAeIZADaDLqwA0XKAEh-nzVWP6dsmc1yjNKgEpr5Hcnednn0ktOazfkUTFHSa21VneMKaV8IPoAcSUlS5MKUS5MKnQz+GJAAGX7M4PqbnqXnZgbTS7v7rs3Y6-BBCs2lSAABzQA8DqAEELbCT2QwvYOlZUKn3sw-aC54o1F31nPOgCDsHiFIdQ8AOSaCOkd+hR-6N7HB1yndMziPHMqCdQCJ+D0nMPT4Ha-Gjhnv2Cr-a7E8-ehPeG3Y6+RUnZOeeob58SAAkkc1bBHhewKB2zon0vocw92Yj3nCU0fK5-ozkDuOAdDx-VriXoOmIy92XL5TSD3AkjaNJE3UyzfQF8+ezXYv2e246-bpUuzACziYAcEjABLRoAMhUqduhp9BEw7u4AmGDdjr8V2g9vEh4AUf1AAQGW8VlRqlswpW97rbAnXjsMger2m+35cVTMKvRAMAGlqNVy1Glx88mAC5PN4HXGyABkGN4qpAAsGiN+bl3FuVtYrvcvguCNV5rxx7blv4-PcNy1RJUpfze7DTiQANVGADgzYv2918wq5TyyMC5wrTDUhvsU9nCxXXkM3te7e4kjkO7fJBb8goLwmSihGQFhAA)

例）JSONスキーマ作成フォームで作成したフォーム
[https://rawseq.github.io/json-editor-sb/](https://rawseq.github.io/json-editor-sb/#schema=N4IgLglmA2CmIC4SFNFQ2UqFWGQlQyB+GQBwwgBpwBPAB3iQHsAjAK1gGMxCRSAnS8tyWAZ0VAA7AIYBbCqEgwKIQGhygej1AsCoswZGbzBsIggOYsAJnwZbSkSoMQhAKgyA27UDzpoDsGBYsBJDGkDqDIDMGQPIMgAwZAqgyAIgyAQAwgAL5EAGZiENDEAuBQcJb2gNOWgAhGKmqWwmxswvFEULCi-AiSSTL2WeSWNPRMLOycsNwQfAki4glSyUiA8DbKRKq1SBpaugZGJmYWSLaOg26oXn5BoREg1BDcABb6BT2VloD4roAueoAQ5oCnpjXqmtp6UZRsosLMSAdg8ESGvMYQpgg5ksCwc52uy1WARC4SIOlggkMbCO0ksgHIDQCkSrdLOMHiwEQBXUSIADaIEA7K5oliAZ00qQBdH7TAGzEH2ByYyE+aEbIikXbmCSJVFIQACRoBAY0AXCbyQDfaYBHKMA3wyAToZAHsM2EAEwxYQDPDNikLl8oUQMVSii+iApXKlaqNZhtcNslQ6IxmLyOFweGVQAw9e1keUhabALUMgGOGQBXDIAihh1IFxkyIhOJCDJABFKABhSgAWUoLAAggBVFgAZUokTA1GEggA1iA6ZsuoLejJAPdegGpzIYkUZR+6TTakAlsUiUXj145IQCUSoAKV3HgBQEyN6w5FL7Gv0NyyR6OPEBx0kgQBY8oA+T3HLEA0AqALrlDzWiATBBAAI4E2AASUXZU097C74-H6AAA$$)

``` json:json
{
	"title": "JSONスキーマ作成 (jdorn/json-editor)",
	"description": "<a href='https://github.com/jdorn/json-editor'>https://github.com/jdorn/json-editor</a><br><a href='https://rawseq.github.io/json-editor-sb/' target='_blank'>https://rawseq.github.io/json-editor-sb/</a><br>右上「項目」ボタンで属性を追加します。",
	"$ref": "#/definitions/property",
	"definitions": {
		"property": {
			"description": "属性情報：右上の「項目」ボタンで属性項目を増減できます。",
			"type": "object",
			"properties": {
				"title": {
					"title": "タイトル",
					"type": "string"
				},
				"type": {
					"title": "種類",
					"type": "string",
					"enum": [
						"string",
						"integer",
						"number",
						"array",
						"object",
						"boolean",
						"null"
					],
					"options": {
						"enum_titles": [
							"文字列(string)",
							"整数(integer)",
							"数値(number)",
							"配列(array)",
							"項目(object)",
							"真偽値 True/False(boolean)",
							"null"
						]
					}
				},
				"format": {
					"title": "形式",
					"type": "string",
					"enum": [
						"text",
						"textarea",
						"number",
						"email",
						"url",
						"tel",
						"date",
						"datetime-local",
						"datetime",
						"month",
						"week",
						"time",
						"range",
						"color",
						"grid",
						"checkbox",
						"table",
						"select",
						"sql",
						"actionscript",
						"batchfile",
						"c",
						"cpp",
						"coffee",
						"csharp",
						"css",
						"dart",
						"django",
						"ejs",
						"erlang",
						"golang",
						"groovy",
						"handlebars",
						"haskell",
						"haxe",
						"html",
						"ini",
						"jade",
						"java",
						"javascript",
						"json",
						"less",
						"lisp",
						"lua",
						"makefile",
						"markdown",
						"matlab",
						"mysql",
						"objectivec",
						"pascal",
						"perl",
						"pgsql",
						"php",
						"python",
						"r",
						"ruby",
						"sass",
						"scala",
						"scss",
						"smarty",
						"sql",
						"stylus",
						"svg",
						"twig",
						"vbscript",
						"xml",
						"yaml"
					]
				},
				"default": {
					"type": "string",
					"title": "規定値"
				},
				"enum": {
					"title": "選択肢",
					"type": "array",
					"items": {
						"title": "選択肢コード",
						"type": "string"
					}
				},
				"properties": {
					"type": "object",
					"title": "項目(object.properties)",
					"description": "右上の「項目」ボタンからコード名を入力して追加してください。",
					"patternProperties": {
						".*": {
							"$ref": "#/definitions/property"
						}
					}
				},
				"patternProperties": {
					"type": "object",
					"title": "パターン項目(object.patternProperties)",
					"description": "右上の「項目」ボタンから正規表現パターンを入力して追加してください。",
					"patternProperties": {
						".*": {
							"$ref": "#/definitions/property"
						}
					}
				},
				"items": {
					"$ref": "#/definitions/property",
					"title": "配列要素(array.items)"
				},
				"readonly": {
					"type": "integer",
					"title": "読み取り専用",
					"enum": [
						0,
						1
					],
					"options": {
						"enum_titles": [
							"いいえ",
							"はい"
						]
					}
				},
				"options": {
					"title": "詳細設定",
					"type": "object",
					"format": "grid",
					"properties": {
						"collapsed": {
							"title": "折り畳んだ状態にする",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"disable_array_add": {
							"title": "配列の追加無効",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"disable_array_delete": {
							"title": "配列の削除無効",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"disable_array_reorder": {
							"title": "配列の並べ替え無効",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"disable_collapse": {
							"title": "折り畳み無効",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"disable_edit_json": {
							"title": "JSON編集無効",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"disable_properties": {
							"title": "項目編集無効",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"no_additional_properties": {
							"title": "項目追加無効",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"hidden": {
							"title": "隠す",
							"type": "boolean",
							"options": {
								"grid_columns": 2
							}
						},
						"grid_columns": {
							"title": "「grid」形式指定時のカラム幅指定(1-12)",
							"type": "integer"
						},
						"enum_titles": {
							"title": "選択肢タイトル（「選択肢コード」と並びを合わせる事）",
							"type": "array",
							"items": {
								"title": "選択肢",
								"type": "string"
							}
						}
					}
				},
				"pattern": {
					"type": "string",
					"title": "入力規則：正規表現"
				},
				"minLength": {
					"type": "string",
					"title": "入力規則（文字列）：最小桁数"
				},
				"maxLength": {
					"type": "string",
					"title": "入力規則（文字列）：最大桁数"
				},
				"minnum": {
					"type": "string",
					"title": "入力規則（文字列）：最小値"
				},
				"maxnum": {
					"type": "string",
					"title": "入力規則（数値）：最大値"
				},
				"minItems": {
					"type": "string",
					"title": "入力規則（数値）：最小要素数"
				},
				"maxItems": {
					"type": "string",
					"title": "入力規則（配列）：最大要素値"
				},
				"uniqueItems": {
					"type": "boolean",
					"title": "入力規則（配列）：要素重複拒否"
				},
				"required": {
					"title": "入力規則（項目）：必須項目",
					"type": "array",
					"items": {
						"title": "項目コード",
						"type": "string"
					}
				},
				"defaultProperties": {
					"title": "規定表示項目（種類が項目の場合）",
					"type": "array",
					"items": {
						"title": "項目コード",
						"type": "string"
					}
				},
				"description": {
					"title": "説明",
					"type": "string",
					"format": "textarea"
				}
			},
			"defaultProperties": [
				"title",
				"type"
			]
		}
	}
}

```