Kiểm tra JSON theo Schema

Dán schema và tài liệu vào để thấy mọi luật bị vi phạm, mỗi lỗi trỏ thẳng vào giá trị gây ra nó. Chạy bằng bộ kiểm tra viết bằng Rust ngay trong trình duyệt — không tải gì lên, và không bao giờ tải tham chiếu ngoài về.

File không bao giờ rời khỏi thiết bị của bạnChưa có schema? Sinh một cái từ tài liệu mẫu.
0
0

Bản draft lấy từ chính schema. Không có khóa $schema thì mặc định là 2020-12.

JSON Schema mô tả hình dạng mà một tài liệu phải có — có những khóa nào, giá trị kiểu gì, khóa nào bắt buộc, khoảng giá trị và mẫu chuỗi nào được chấp nhận. Trang này đối chiếu tài liệu với schema và báo mọi chỗ hai bên lệch nhau, mà không thứ nào rời khỏi trình duyệt.

Đọc một lỗi

Mỗi lỗi mang hai vị trí, và chúng trả lời hai câu hỏi khác nhau:

Trỏ vàoVí dụTrả lời
Đường dẫn giá trịtài liệu của bạnitems[0].pricesai cái gì
Đường dẫn luậtschema của bạn/properties/items/items/properties/price/typeluật nào nói vậy

Đường dẫn giá trị viết theo đúng cách bạn sẽ lấy giá trị đó trong code, nên items[0].price đọc thẳng xuống tài liệu là ra. Khóa nào không phải định danh thường thì được bọc nháy — khóa có dấu chấm bên trong hiện thành ["a.b"] chứ không âm thầm bị đọc thành hai tầng.

Đường dẫn luật là một JSON pointer trỏ vào schema, đó là cách bạn tìm ra từ khóa cần sửa khi thứ sai là schema chứ không phải tài liệu.

Bản draft lấy từ chính schema của bạn

Bộ kiểm tra đọc khóa $schema rồi áp luật của đúng draft đó. Draft 4, 6, 7, 2019-09 và 2020-12 đều được hỗ trợ, và điều này quan trọng vì các draft khác nhau thật:

  • exclusiveMinimum ở draft 4 là một cờ boolean, từ draft 6 trở đi thành một con số riêng.
  • items dạng mảng schema đổi thành prefixItems ở 2020-12.
  • definitions đổi thành $defs.

Schema không có khóa $schema sẽ được kiểm theo 2020-12.

Mẹo: Nếu một schema chạy ở đây khác với ở công cụ khác, hãy soi dòng $schema trước tiên. Hai bộ kiểm tra bất đồng trên cùng một tài liệu thường là do chúng chọn draft khác nhau, chứ không phải một bên sai.

Tham chiếu ra ngoài bị từ chối có chủ ý

Một $ref trỏ tới file khác hay URL sẽ không giải được. Đây không phải tính năng làm dở: cách duy nhất để giải nó là tải nó về, mà tải về là phá vỡ lời hứa của trang này. Một bộ kiểm tra chịu tải URL nằm trong schema của bạn là thứ có thể bị lợi dụng để lộ ra bạn làm việc với schema nào, của ai.

Tham chiếu bên trong schema thì chạy bình thường. Chuyển thứ bạn cần vào $defs rồi trỏ tới bằng con trỏ nội bộ:

{
  "$defs": { "money": { "type": "number", "minimum": 0 } },
  "type": "object",
  "properties": { "price": { "$ref": "#/$defs/money" } }
}

Số giữ nguyên giá trị thật

Việc kiểm tra chạy trên văn bản gốc của từng con số chứ không trên bản double đã chuyển đổi. Nhờ vậy số nguyên 30 chữ số vẫn là integer, và vẫn so sánh đúng với minimum, maximum, multipleOf. Đây là khác biệt thật: ở bộ kiểm tra parse sang double trước, một mã định danh dài đã bị hỏng ngầm trước khi bất kỳ luật nào được áp, và báo cáo sẽ mô tả một giá trị bạn chưa từng gửi.

Vài lỗi hay gặp và ý nghĩa của chúng

  • want string, but got number — lệch kiểu, thường là một trường số bị bọc nháy hoặc một trường chuỗi lại về dạng số. Hãy soi thứ sinh ra tài liệu, đừng soi schema.
  • missing properties — thiếu một khóa required. Nếu khóa đó thật sự là tùy chọn thì thứ cần sửa là schema.
  • must not have additional properties — schema đặt additionalProperties: false mà tài liệu mang theo khóa nó không khai báo. Hay gặp sau khi API thêm trường mới.
  • does not match pattern — một pattern hoặc format đã bác giá trị. Biểu thức chính quy trong schema không tự neo hai đầu, nên khớp một phần cũng tính là khớp.

Giới hạn

Mười megabyte cho schema và mười megabyte cho tài liệu — ngưỡng của thứ một tab trình duyệt giữ được thoải mái, không phải ngưỡng của bộ kiểm tra.

Câu hỏi thường gặp

Schema và dữ liệu của tôi có bị tải lên đâu không?
Không. Cả hai được đối chiếu ngay trong tab trình duyệt bằng bộ kiểm tra viết bằng Rust biên dịch sang WebAssembly, và không request nào mang chúng rời khỏi máy. Mở tab Network trong lúc kiểm tra sẽ thấy trống trơn. Điều đó có ý nghĩa khi tài liệu là bản xuất dữ liệu khách hàng, phản hồi API nội bộ, hay một file cấu hình bạn không được phép dán lên máy chủ của người khác.
Hỗ trợ những bản draft nào?
Draft 4, 6, 7, 2019-09 và 2020-12. Bản draft được đọc từ khóa schema ở đầu file schema của bạn, nên schema nào tự khai báo draft thì được kiểm theo đúng luật của draft đó. Thiếu khai báo thì mặc định 2020-12, vốn là đặc tả hiện hành và là lựa chọn an toàn cho schema mới.
Sao tham chiếu tới file hay URL khác lại lỗi?
Vì giải nó nghĩa là phải tải nó về, mà trang này không bao giờ gửi request nào. Đây là đánh đổi có chủ ý chứ không phải tính năng còn thiếu: một bộ kiểm tra âm thầm tải URL trong schema của bạn là một bộ kiểm tra có thể bị lợi dụng để lộ ra bạn đang dùng schema nào, và của ai. Hãy nhúng thứ bạn cần vào khóa definitions, khi đó tham chiếu giải được ngay tại chỗ.
Nó có dừng ở lỗi đầu tiên không?
Không, nó báo mọi luật bị vi phạm, mỗi lỗi kèm con trỏ tới giá trị gây ra và con trỏ tới từ khóa đã bác. Sửa từng lỗi một rồi chạy lại là cách chậm nhất để xử lý một tài liệu lệch chuẩn, nên danh sách đầy đủ là mặc định và là chế độ duy nhất.
Hai đường dẫn trong mỗi lỗi nghĩa là gì?
Cái thứ nhất trỏ vào tài liệu của bạn, nên 'items[0].price' chính là giá trị sai. Cái thứ hai trỏ vào schema, nên '/properties/items/items/properties/price/type' là đúng từ khóa đã bác nó. Hai cái cùng nhau trả lời cả hai nửa của câu hỏi: sai ở đâu, và luật nào nói vậy.
Số quá lớn với JavaScript thì sao?
Vẫn đúng. Số giữ nguyên văn bản gốc suốt quá trình kiểm tra thay vì bị parse thành double trước, nên số nguyên 30 chữ số vẫn được coi là integer và vẫn so sánh đúng với minimum và maximum. Bộ kiểm tra viết bằng JavaScript thường không làm được, vì giá trị đã hỏng trước khi luật kịp chạy.
Có giới hạn dung lượng không?
Mười megabyte cho mỗi bên, schema và tài liệu. Ngưỡng đó để giữ tab trình duyệt còn mượt chứ không nhằm hạn chế sử dụng; schema gần như không bao giờ chạm tới, còn tài liệu mà chạm tới thì thường thuộc về một pipeline xử lý dòng chứ không phải một ô nhập liệu.