🐷

今更JSON Schema入門

2023/08/25に公開

背景

Protocol Buffersに入門する前に同じようなJSON Schemaも軽く抑えておきたい。
https://json-schema.org/

本題

定義はお馴染みのJSONで書くことが可能。

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "age": {
      "type": "integer",
      "minimum": 0
    }
  },
  "required": ["name"]
}

こういうJSON Schemaを定義することで、

  • nameはstring型なんやな
  • ageはinteger型なんやな
  • ageは0以上なんやな
  • nameは必須だけど、ageは無くてもいいんやな
    ということが分かります。

雑にこういうところで通すとわかりやすいです。
https://jsonschema.dev/

  • Success

  • Fail

JSON Schemaを書くことで、Goの構造体やPythonのデータクラス定義を自動生成できます。
雑に下記を使って、各種言語に変換してもらえます。
https://app.quicktype.io/

package main

import "encoding/json"

func UnmarshalWelcome(data []byte) (Welcome, error) {
	var r Welcome
	err := json.Unmarshal(data, &r)
	return r, err
}

func (r *Welcome) Marshal() ([]byte, error) {
	return json.Marshal(r)
}

type Welcome struct {
	Schema     string     `json:"$schema"`
	Type       string     `json:"type"`
	Properties Properties `json:"properties"`
	Required   []string   `json:"required"`
}

type Properties struct {
	Name Name `json:"name"`
	Age  Age  `json:"age"`
}

type Age struct {
	Type    string `json:"type"`
	Minimum int64  `json:"minimum"`
}

type Name struct {
	Type string `json:"type"`
}

TypeScriptにも変換可能なので、定義を書いておけば、フロントとバックエンドで頭で変換して定義を書く必要はなくなるし、お互いの認識合わせが容易になりそうです。
しかし、下記デメリットはあるのかなと感じました。

  • 書きなれているjsonで書けるのは良いが、個人的にスキーマを読む際にどうしても目で追わなくてはいけない
  • 公式で紹介されている自動生成するライブラリが3rd頼りで、メンテされてないものもいくつかあるので、選定は気をつけないといけない
    https://json-schema.org/implementations.html
  • これはJSONの話ですが、シンプルな文法故にtypoすると悲しみを覚えます(末にカンマを付けてしまう/シングルクオートで閉じてしまう)。またコメントも気軽に書けません。

次回はProtocol Buffersキャッチアップしたいと思います。
ありがとうございました。

Discussion