# [Java] JSON Schema (v2020-12)
[TOC]
## type
允許的型態有
* object (需要搭配 properties 定義 Key-value)
* array (需要搭配 items 定義 array element)
* string
* integer (整數)
* number (允許小數)
* boolean
* null
範例:
表示只允許字串
```=json
"type": "string"
```
表示允許字串及null
```=json
"type": ["string", "null"]
```
## string length
```
x ≥ minLength
x ≤ maxLength
```
## number range
檢查最小值、最大值,如有小數建議搭配 multipleOf,可以限制範圍及小數格式。
```
x ≥ minimum
x > exclusiveMinimum
x ≤ maximum
x < exclusiveMaximum
```
範例:
```=json
"price": {
"type": "integer",
"description": "允許0~99的數值",
"minimum": 0,
"maximum": 99
},
"discount": {
"type": "number",
"description": "允許0~100的數值,可到小數兩位",
"minimum": 0,
"maximum": 100,
"multipleOf": 0.01
},
```
## format
`"format": "date-time"` 依照 RFC 3339 規定必須是像 `"2025-03-03T17:52:26Z"` 或 `"2025-03-03T17:52:26+08:00"` 的 ISO 8601 格式(帶有 T 與時區資訊)
```=json
"create_date": {
"type": "string",
"format": "date-time"
},
```
## pattern
數字及字串都能使用正規表達式
範例:
字串要檢查日期格式
```=json
"birthday": {
"type": "string",
"pattern": "^(\\d{8}|00000000)$",
"description": "日期格式為 yyyyMMdd 或預設 00000000"
},
```
數字要檢查長度符合8 (單純檢查數值大小建議使用 minimum 或 maximum)
```=json
"serial_no": {
"type": "integer",
"pattern": "^\\d{8}$",
"description": "產品編號必須是8碼數字"
},
```
## required
用於 object 型態,檢查有沒有缺少的 key,key不能用正則表達式
範例:
```=json
"employee": {
"type": "object",
"required": [ "name" ],
"properties": {
"name": {
"type": "string",
"maxLength": 20
},
"memo": {
"type": ["string", "null"],
"maxLength": 150
},
...
},
```
以上面的 schema 來看,A的資料會通過驗證,但B會拋出錯誤訊息
A
```=json
{
"employee": {
"name": "Alice",
"memo": "備註內容"
}
}
```
B
```=json
{
"employee": {
"memo": "備註內容"
}
}
```
## additionalProperties
用於 object 型態,檢查 keys 有沒有符合,可用來檢查有沒有多餘欄位
| 設定 | 說明 |
| --- | --- |
| `true`(預設) | 允許出現未定義的欄位 |
| `false` | 禁止所有未定義欄位(常用來防止多餘欄位) |
| `schema` | 自訂「未列出的欄位」的格式,例如所有多餘欄位都必須是 string <br> `"additionalProperties": { "type": "string" }` |
範例:
```=json
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "integer" }
},
"required": ["name", "age"],
"additionalProperties": false
},
```
## patternProperties
如果有多個相似的 key 可以用正規表達式定義欄位名稱,如:XYZ-1、XYZ-05、XYZ-20...等,可以用 "^XYZ-[0-9]{1,3}$"
```=json
{
"name": "John Doe",
"age": 25,
"XYZ-1": "HR",
"XYZ-05": 2345,
"XYZ-20": null
}
```
```=json
{
"type":"object",
"patternProperties": {
"^XYZ-[0-9]{1,3}$": {
"type": ["string". "integer", "null"]
}
}
}
```
參考資料:
[JSON Schema v2020-12](https://json-schema.org/draft/2020-12/schema)
[Json Schema Validator](https://www.jsonschemavalidator.net/)
[JSON Schema - Creating your first schema](https://json-schema.org/learn/getting-started-step-by-step)
[驗證資料的好幫手 - JSON Schema Validator #2](https://github.com/Hsueh-Jen/blog/issues/2)