فهم JSON Schema: دليل شامل
تعلم كيفية استخدام JSON Schema للتحقق من صحة البيانات. التعريفات، الأمثلة، وأفضل الممارسات.
Big JSON Team
• Technical WriterExpert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.
# فهم JSON Schema: دليل شامل
JSON Schema هو معيار قوي للتحقق من صحة وتوثيق بيانات JSON.
ما هو JSON Schema؟
التعريف
JSON Schema هو JSON document يصف بنية ومحتوى JSON data.
الفوائد الرئيسية
- التحقق - التأكد من صحة البيانات
- التوثيق - توثيق API تلقائياً
- التحقق من النوع - التأكد من أنواع البيانات
- التحقق من الصحة - قواعد معقدة
- الأدوات - توليد النماذج والكود
Schema الأساسي
مثال بسيط
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"الاسم": {
"type": "string"
},
"العمر": {
"type": "number"
}
},
"required": ["الاسم"]
}
البيانات الصالحة
{
"الاسم": "أحمد",
"العمر": 30
}
البيانات غير الصالحة
{
"العمر": 30
}
// خطأ: الاسم مطلوب
أنواع البيانات
String
{
"type": "object",
"properties": {
"الاسم": {
"type": "string",
"minLength": 2,
"maxLength": 50,
"pattern": "^[\u0600-\u06FF\s]+$"
}
}
}
Number
{
"type": "object",
"properties": {
"العمر": {
"type": "number",
"minimum": 0,
"maximum": 150
},
"الراتب": {
"type": "number",
"multipleOf": 100
}
}
}
Integer
{
"type": "object",
"properties": {
"العدد": {
"type": "integer",
"minimum": 1,
"maximum": 100
}
}
}
Boolean
{
"type": "object",
"properties": {
"نشط": {
"type": "boolean"
}
}
}
Null
{
"type": "object",
"properties": {
"القيمة": {
"type": ["string", "null"]
}
}
}
Array
{
"type": "object",
"properties": {
"المهارات": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
}
}
Object
{
"type": "object",
"properties": {
"العنوان": {
"type": "object",
"properties": {
"المدينة": {"type": "string"},
"الرمز": {"type": "string"}
},
"required": ["المدينة"]
}
}
}
القيود والتحقق
Required Fields
{
"type": "object",
"properties": {
"الاسم": {"type": "string"},
"البريد": {"type": "string"}
},
"required": ["الاسم", "البريد"]
}
Enum (القيم المحددة)
{
"type": "object",
"properties": {
"الحالة": {
"type": "string",
"enum": ["نشط", "معلق", "محذوف"]
}
}
}
Pattern (النمط)
{
"type": "object",
"properties": {
"البريد": {
"type": "string",
"pattern": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"
},
"الهاتف": {
"type": "string",
"pattern": "^\+?[0-9]{10,15}$"
}
}
}
Format
{
"type": "object",
"properties": {
"البريد": {
"type": "string",
"format": "email"
},
"الموقع": {
"type": "string",
"format": "uri"
},
"التاريخ": {
"type": "string",
"format": "date"
},
"الوقت": {
"type": "string",
"format": "date-time"
}
}
}
Schema المتقدم
الإشارات ($ref)
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"عنوان": {
"type": "object",
"properties": {
"المدينة": {"type": "string"},
"الشارع": {"type": "string"}
}
}
},
"type": "object",
"properties": {
"عنوان_المنزل": {
"$ref": "#/definitions/عنوان"
},
"عنوان_العمل": {
"$ref": "#/definitions/عنوان"
}
}
}
AllOf (الكل)
{
"allOf": [
{
"type": "object",
"properties": {
"الاسم": {"type": "string"}
}
},
{
"type": "object",
"properties": {
"العمر": {"type": "number"}
}
}
]
}
AnyOf (أي)
{
"type": "object",
"properties": {
"القيمة": {
"anyOf": [
{"type": "string"},
{"type": "number"}
]
}
}
}
OneOf (واحد فقط)
{
"type": "object",
"properties": {
"الدفع": {
"oneOf": [
{
"properties": {
"الطريقة": {"const": "بطاقة"},
"رقم_البطاقة": {"type": "string"}
}
},
{
"properties": {
"الطريقة": {"const": "نقدي"},
"المبلغ": {"type": "number"}
}
}
]
}
}
}
Not (ليس)
{
"type": "object",
"properties": {
"القيمة": {
"not": {
"type": "null"
}
}
}
}
أمثلة عملية
مخطط المستخدم
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "مستخدم",
"description": "مخطط لبيانات المستخدم",
"type": "object",
"properties": {
"id": {
"type": "integer",
"minimum": 1
},
"الاسم": {
"type": "string",
"minLength": 2,
"maxLength": 100
},
"البريد": {
"type": "string",
"format": "email"
},
"العمر": {
"type": "integer",
"minimum": 18,
"maximum": 100
},
"الحالة": {
"type": "string",
"enum": ["نشط", "معلق", "محذوف"],
"default": "نشط"
},
"الأدوار": {
"type": "array",
"items": {
"type": "string",
"enum": ["مستخدم", "مدير", "مشرف"]
},
"minItems": 1,
"uniqueItems": true
},
"العنوان": {
"type": "object",
"properties": {
"المدينة": {"type": "string"},
"الشارع": {"type": "string"},
"الرمز": {
"type": "string",
"pattern": "^[0-9]{5}$"
}
},
"required": ["المدينة"]
},
"تاريخ_التسجيل": {
"type": "string",
"format": "date-time"
}
},
"required": ["id", "الاسم", "البريد"],
"additionalProperties": false
}
مخطط الطلب
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "طلب",
"type": "object",
"properties": {
"id": {"type": "integer"},
"المستخدم_id": {"type": "integer"},
"العناصر": {
"type": "array",
"items": {
"type": "object",
"properties": {
"المنتج_id": {"type": "integer"},
"الكمية": {
"type": "integer",
"minimum": 1
},
"السعر": {
"type": "number",
"minimum": 0
}
},
"required": ["المنتج_id", "الكمية", "السعر"]
},
"minItems": 1
},
"المجموع": {
"type": "number",
"minimum": 0
},
"الحالة": {
"type": "string",
"enum": ["جديد", "معالج", "مشحون", "مكتمل"]
}
},
"required": ["id", "المستخدم_id", "العناصر", "المجموع"]
}
التحقق برمجياً
JavaScript
import Ajv from 'ajv';
const ajv = new Ajv();
// المخطط
const schema = {
type: 'object',
properties: {
الاسم: { type: 'string' },
العمر: { type: 'number', minimum: 0 }
},
required: ['الاسم']
};
// تجميع المخطط
const validate = ajv.compile(schema);
// البيانات
const data = {
الاسم: 'أحمد',
العمر: 30
};
// التحقق
const valid = validate(data);
if (valid) {
console.log('البيانات صالحة');
} else {
console.log('أخطاء:', validate.errors);
}
مع TypeScript
import Ajv from 'ajv';
interface User {
الاسم: string;
العمر: number;
}
const ajv = new Ajv();
const schema = {
type: 'object',
properties: {
الاسم: { type: 'string' },
العمر: { type: 'number' }
},
required: ['الاسم', 'العمر']
};
const validate = ajv.compile<User>(schema);
function validateUser(data: unknown): User {
if (validate(data)) {
return data;
}
throw new Error(JSON.stringify(validate.errors));
}
Python
import jsonschema
from jsonschema import validate
# المخطط
schema = {
"type": "object",
"properties": {
"الاسم": {"type": "string"},
"العمر": {"type": "number", "minimum": 0}
},
"required": ["الاسم"]
}
# البيانات
data = {
"الاسم": "أحمد",
"العمر": 30
}
# التحقق
try:
validate(instance=data, schema=schema)
print("البيانات صالحة")
except jsonschema.exceptions.ValidationError as e:
print(f"خطأ: {e.message}")
التحقق المخصص
JavaScript
import Ajv from 'ajv';
const ajv = new Ajv();
// كلمة رئيسية مخصصة
ajv.addKeyword({
keyword: 'isArabic',
validate: function(schema, data) {
if (typeof data !== 'string') return false;
// فحص إذا كان النص يحتوي على أحرف عربية
return /[-ۿ]/.test(data);
}
});
const schema = {
type: 'object',
properties: {
الاسم: {
type: 'string',
isArabic: true
}
}
};
const validate = ajv.compile(schema);
console.log(validate({ الاسم: 'أحمد' })); // true
console.log(validate({ الاسم: 'Ahmed' })); // false
توليد Schema من البيانات
JavaScript
function generateSchema(data) {
if (data === null) {
return { type: 'null' };
}
if (Array.isArray(data)) {
return {
type: 'array',
items: data.length > 0 ? generateSchema(data[0]) : {}
};
}
if (typeof data === 'object') {
const properties = {};
for (const key in data) {
properties[key] = generateSchema(data[key]);
}
return {
type: 'object',
properties
};
}
return { type: typeof data };
}
// الاستخدام
const data = {
الاسم: 'أحمد',
العمر: 30,
المهارات: ['JavaScript', 'Python']
};
const schema = generateSchema(data);
console.log(JSON.stringify(schema, null, 2));
أدوات JSON Schema
1. مولدات Schema
- quicktype - توليد Schema من JSON
- json-schema-generator - توليد تلقائي
- Schema.org - مخططات جاهزة
2. محققات
- ajv - الأسرع لـ JavaScript
- jsonschema - لـ Python
- JSON Schema Validator - أدوات عبر الإنترنت
3. أدوات توثيق
- docson - توثيق Schema
- json-schema-faker - بيانات وهمية من Schema
أفضل الممارسات
1. استخدم $schema
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object"
}
2. أضف title و description
{
"title": "مستخدم",
"description": "مخطط بيانات المستخدم",
"type": "object",
"properties": {
"الاسم": {
"type": "string",
"description": "الاسم الكامل للمستخدم"
}
}
}
3. استخدم $ref للتكرار
{
"definitions": {
"عنوان": {
"type": "object",
"properties": {
"المدينة": {"type": "string"}
}
}
},
"properties": {
"العنوان": {"$ref": "#/definitions/عنوان"}
}
}
4. حدد additionalProperties
{
"type": "object",
"properties": {
"الاسم": {"type": "string"}
},
"additionalProperties": false
}
5. استخدم default
{
"properties": {
"الحالة": {
"type": "string",
"default": "نشط"
}
}
}
حالات استخدام حقيقية
1. التحقق من API
// Express middleware
function validateRequest(schema) {
return (req, res, next) => {
const validate = ajv.compile(schema);
if (validate(req.body)) {
next();
} else {
res.status(400).json({
error: 'بيانات غير صالحة',
details: validate.errors
});
}
};
}
// الاستخدام
app.post('/users', validateRequest(userSchema), (req, res) => {
// البيانات مضمونة صحيحة
});
2. ملفات التكوين
import fs from 'fs';
function loadConfig(filename, schema) {
const data = JSON.parse(fs.readFileSync(filename, 'utf8'));
const validate = ajv.compile(schema);
if (!validate(data)) {
throw new Error('ملف التكوين غير صالح: ' + JSON.stringify(validate.errors));
}
return data;
}
3. توليد النماذج
استخدام Schema لتوليد نماذج HTML تلقائياً.
الملخص
JSON Schema:
- معيار قوي للتحقق
- توثيق تلقائي
- دعم واسع
- أدوات كثيرة
- أفضل ممارسات
استخدم JSON Schema لبيانات موثوقة!
مقالات ذات صلة
ما هو JSON؟ دليل شامل للمبتدئين
تعلم ما هو JSON، قواعد الصياغة، أنواع البيانات، وحالات الاستخدام. دليل شامل للمبتدئين لفهم JavaScript Object Notation وأهميته في تطوير البرمجيات الحديثة.
JSON APIs وخدمات REST
تعلم كيفية العمل مع JSON في REST APIs. أفضل الممارسات، أمثلة، وتقنيات متقدمة.
بنيات JSON المتقدمة: دليل شامل
تعلم كيفية العمل مع بنيات JSON المعقدة، الأنماط، الأداء، وأفضل الممارسات.