Đối với các cấu trúc JSON phức tạp, mặc dù có thể nhanh chóng trích xuất các giá trị tương ứng bằng JSONPath, nhưng việc sử dụng JSONSchema để xác thực toàn bộ cấu trúc và kiểu dữ liệu của các trường trong phản hồi JSON lại tiện lợi hơn nhiều.
Cách cài đặt:
pip install jsonschema
Sử Dụng Cơ Bản
Lấy phản hồi từ ví dụ trên làm minh họa:
{
"args": {
"age": "12",
"name": "Kevin"
},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.22.0",
"X-Amzn-Trace-Id": "Root=1-5e7f618f-30ba932936a4a8e64ef5ea06"
},
"origin": "111.202.167.11",
"url": "https://httpbin.org/get?name=Kevin&age=12"
}
Toàn bộ cấu trúc JSON có thể được mô tả như sau: tổng thể là kiểu object, chứa bốn thuộc tính: args, headers, origin, và url. Trong đó, args và headers là kiểu object, còn origin và url là kiểu string. Sử dụng cú pháp JSONSchema để mô tả:
{
"type": "object",
"properties": {
"args": {"type": "object"},
"headers": {"type": "object"},
"origin": {"type": "string"},
"url": {"type": "string"}
}
}
Đối với object, bạn cũng có thể sử dụng từ khóa required để chỉ định các thuộc tính bắt buộc phải có. Đối với args và headers, bạn có thể thêm properties để mô tả các thuộc tính con của chúng. Đối với string, có thể sử dụng trường pattern để chỉ định biểu thức chính quy mà chuỗi phải khớp.
Các kiểu dữ liệu trong JSONSchema bao gồm bảy loại: string, number, integer, array, object, boolean, và null. Trong đó, number bao gồm cả số nguyên và số thực, còn integer chỉ giới hạn ở số nguyên. Các từ khóa thường dùng cho từng kiểu trong JSONSchema được liệt kê trong Bảng 3.3.
Các Từ Khóa Thường Dùng Trong Schema
Cấp Cao Nhất
$schema: Chỉ định phiên bản giao thức JSONSchema được sử dụng.title: Tiêu đề của quy tắc.description: Mô tả quy tắc.
Chung
type: Kiểu dữ liệu, bao gồm string, number, integer, array, object, boolean, null.
String
miniLength: Độ dài tối thiểu.maxLength: Độ dài tối đa.pattern: Biểu thức chính quy cần khớp.
Number/Integer
minimum: Giá trị tối thiểu. Kết hợp với"exclusiveMinimum": Trueđể không bao gồm giá trị bằng.maximum: Giá trị tối đa. Kết hợp với"exclusiveMaximum": Trueđể không bao gồm giá trị bằng.multipleOf: Phải chia hết cho số đã chỉ định.
Object
properties: Các thuộc tính con.patternProperties: Tên thuộc tính con phải thỏa mãn biểu thức chính quy.required: Các thuộc tính con bắt buộc.
Array
items: Các phần tử con.required: Các phần tử con bắt buộc.miniItems: Số lượng phần tử con tối thiểu.maxItems: Số lượng phần tử con tối đa.
Ví Dụ Sử Dụng
Ví dụ hoàn chỉnh như sau:
import requests
import jsonschema
res = requests.get('https://httpbin.org/get?name=Kevin&age=12')
schema = {
"type": "object",
"properties": {
"args": {
"type": "object",
"required": ["name", "age"],
"properties": {
"name": {"type": "string", "pattern": "^Kevin$"},
"age": {"type": "string", "pattern": "^12$"}
}
},
"headers": {"type": "object"},
"origin": {"type": "string", "pattern": "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"},
"url": {"type": "string"}
}
}
jsonschema.validate(res.json(), schema)
Trong ví dụ trên, từ khóa required chỉ định rằng args phải có hai thuộc tính con là name và age.
Trường pattern của name sử dụng "^Kevin$" để đảm bảo nó bắt đầu bằng 'K' và kết thúc bằng 'n', tức là hoàn toàn bằng 'Kevin'.
Tương tự, khi xác thực thành công, sẽ không có đầu ra nào; khi xác thực thất bại, một ngoại lệ sẽ được ném ra.