JSON Schema Validation là gì?
JSON Schema validation là quá trình kiểm tra xem một tài liệu JSON có tuân thủ các ràng buộc về cấu trúc và giá trị được định nghĩa trong JSON Schema hay không. Bản thân schema cũng là một tài liệu JSON mô tả hình dạng dữ liệu mong đợi: những thuộc tính nào là bắt buộc, kiểu dữ liệu của chúng phải là gì, phạm vi cho phép của số, mẫu chuỗi, độ dài mảng và nhiều hơn nữa. Đặc tả JSON Schema được duy trì tại json-schema.org và được xuất bản dưới dạng một loạt các bản thảo IETF, trong đó Draft 7 và Draft 2020-12 được áp dụng rộng rãi nhất.
Trong khi xác thực JSON thuần túy chỉ kiểm tra cú pháp (dấu ngoặc có khớp không? chuỗi có được đặt trong dấu ngoặc kép không?), xác thực schema đi xa hơn. Nó trả lời các câu hỏi như: phản hồi từ API này có chứa trường "id" luôn là số nguyên không? Trường "status" có phải là một trong ba giá trị được phép không? Các đối tượng lồng nhau có đúng cấu trúc không? Loại kiểm tra cấu trúc này bắt được các lỗi mà kiểm tra cú pháp bỏ sót hoàn toàn, vì JSON hợp lệ về mặt cú pháp vẫn có thể sai về mặt ngữ nghĩa đối với ứng dụng của bạn.
JSON Schema được sử dụng trong các định nghĩa OpenAPI/Swagger, xác thực tệp cấu hình, xác thực biểu mẫu, ràng buộc tài liệu cơ sở dữ liệu và kiểm thử tự động. Các công cụ như Ajv (JavaScript), jsonschema (Python) và check-jsonschema (CLI) triển khai đặc tả này để bạn có thể xác thực dữ liệu theo chương trình. Công cụ xác thực trực tuyến này cho phép bạn dán cả schema và tài liệu dữ liệu để kiểm tra sự phù hợp ngay lập tức, mà không cần cài đặt bất kỳ thư viện nào.
Tại sao sử dụng công cụ xác thực JSON Schema trực tuyến?
Viết schema và gỡ lỗi các lỗi xác thực theo cách thủ công rất chậm. Công cụ xác thực JSON Schema trực tuyến cung cấp phản hồi tức thì về việc dữ liệu của bạn có khớp với schema hay không, với thông báo lỗi rõ ràng chỉ đến đúng thuộc tính bị lỗi.
Các trường hợp sử dụng JSON Schema Validation
Tài liệu tham khảo các từ khóa JSON Schema
Một JSON Schema được xây dựng từ các từ khóa, mỗi từ khóa áp đặt một ràng buộc lên dữ liệu được xác thực. Bảng dưới đây liệt kê các từ khóa được sử dụng phổ biến nhất trong Draft 7 và các phiên bản sau. Mỗi từ khóa có thể kết hợp với các từ khóa khác trong cùng một đối tượng schema.
| Từ khóa | Mục đích | Ví dụ |
|---|---|---|
| type | Restricts the data type | "type": "string" |
| properties | Defines expected object keys and their schemas | "properties": { "name": { "type": "string" } } |
| required | Lists mandatory properties | "required": ["id", "name"] |
| items | Schema for array elements | "items": { "type": "number" } |
| enum | Restricts value to a fixed set | "enum": ["active", "inactive"] |
| pattern | Regex constraint on strings | "pattern": "^[A-Z]{2}\\d{4}$" |
| minimum / maximum | Numeric range bounds | "minimum": 0, "maximum": 100 |
| minLength / maxLength | String length bounds | "minLength": 1, "maxLength": 255 |
| $ref | Reuses another schema by URI | "$ref": "#/$defs/address" |
| additionalProperties | Controls extra keys in objects | "additionalProperties": false |
| anyOf / oneOf / allOf | Combines multiple schemas logically | "anyOf": [{ "type": "string" }, { "type": "null" }] |
| if / then / else | Conditional schema application | "if": { "properties": { "type": { "const": "email" } } } |
So sánh các phiên bản JSON Schema: Draft 7 so với 2019-09 so với 2020-12
JSON Schema đã trải qua nhiều phiên bản draft. Draft 7 (xuất bản năm 2018) được hỗ trợ rộng rãi nhất trong các công cụ. Draft 2019-09 giới thiệu $defs (thay thế definitions), unevaluatedProperties và $recursiveRef. Draft 2020-12 (phiên bản ổn định mới nhất) thay thế $recursiveRef bằng $dynamicRef và giới thiệu prefixItems để xác thực tuple. Khi chọn phiên bản draft, hãy kiểm tra thư viện xác thực của bạn có hỗ trợ nó không. Ajv hỗ trợ cả ba draft. Thư viện jsonschema của Python hỗ trợ đến 2020-12 kể từ phiên bản 4.0.
| Tính năng | Draft 7 | Draft 2019-09 | Draft 2020-12 |
|---|---|---|---|
| $schema URI | draft-07/schema# | 2019-09/schema | 2020-12/schema |
| if / then / else | Yes | Yes | Yes |
| $defs (definitions) | definitions | $defs | $defs |
| $ref alongside keys | No (sibling ignored) | Yes | Yes |
| $dynamicRef | No | No ($recursiveRef) | Yes |
| prefixItems | No (use items array) | No (use items array) | Yes |
| unevaluatedProperties | No | Yes | Yes |
| $vocabulary | No | Yes | Yes |
Ví dụ mã nguồn
Các ví dụ này minh họa cách xác thực JSON theo schema theo chương trình. Mỗi ví dụ sử dụng một thư viện được bảo trì tốt cho hệ sinh thái ngôn ngữ của nó.
import Ajv from 'ajv';
const ajv = new Ajv();
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
age: { type: 'integer', minimum: 0 },
email: { type: 'string', format: 'email' }
},
required: ['name', 'email'],
additionalProperties: false
};
const data = { name: 'Alice', age: 30, email: 'alice@example.com' };
const validate = ajv.compile(schema);
const valid = validate(data);
console.log(valid); // → true
console.log(validate.errors); // → null
// Invalid data — missing required "email"
validate({ name: 'Bob', age: 25 });
console.log(validate.errors);
// → [{ instancePath: '', keyword: 'required', params: { missingProperty: 'email' } }]from jsonschema import validate, ValidationError
schema = {
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"age": {"type": "integer", "minimum": 0},
"tags": {
"type": "array",
"items": {"type": "string"},
"uniqueItems": True
}
},
"required": ["name"]
}
# Valid data
validate(instance={"name": "Alice", "age": 30, "tags": ["admin"]}, schema=schema)
# → No exception raised
# Invalid data — wrong type for "age"
try:
validate(instance={"name": "Alice", "age": "thirty"}, schema=schema)
except ValidationError as e:
print(e.message)
# → 'thirty' is not of type 'integer'
print(e.json_path)
# → $.agepackage main
import (
"fmt"
"strings"
"github.com/santhosh-tekuri/jsonschema/v5"
)
func main() {
schemaJSON := `{
"type": "object",
"properties": {
"id": { "type": "integer" },
"status": { "enum": ["active", "inactive"] }
},
"required": ["id", "status"]
}`
compiler := jsonschema.NewCompiler()
compiler.AddResource("schema.json", strings.NewReader(schemaJSON))
schema, _ := compiler.Compile("schema.json")
// Valid data
data := map[string]interface{}{"id": 1, "status": "active"}
err := schema.Validate(data)
fmt.Println(err) // → <nil>
// Invalid — missing "status"
bad := map[string]interface{}{"id": 2}
err = schema.Validate(bad)
fmt.Println(err) // → validation failed: missing properties: 'status'
}# Install via pip pip install check-jsonschema # Validate a file against a schema check-jsonschema --schemafile schema.json data.json # → ok -- validation done # Validate against a remote schema (e.g., GitHub Actions workflow) check-jsonschema --builtin-schema vendor.github-workflows my-workflow.yml # Validate multiple files at once check-jsonschema --schemafile schema.json file1.json file2.json file3.json