← العودة إلى المدونة

بنيات JSON المتقدمة: دليل شامل

تعلم كيفية العمل مع بنيات JSON المعقدة، الأنماط، الأداء، وأفضل الممارسات.

Big JSON Team16 دقيقة للقراءةadvanced
B

Big JSON Team

Technical Writer

Expert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.

16 دقيقة قراءة

# بنيات JSON المتقدمة: دليل شامل

تعلم تصميم بنيات JSON معقدة وفعالة.

مقدمة

متى تحتاج بنيات متقدمة؟

  • تطبيقات معقدة
  • بيانات متعددة المستويات
  • أنظمة كبيرة
  • APIs متقدمة

ما ستتعلمه

  • التعشيش العميق
  • الأنماط الشائعة
  • تحسين الأداء
  • أمثلة عملية

البنيات المتداخلة

التعشيش البسيط

{

"user": {

"id": 1,

"name": "أحمد محمد",

"address": {

"street": "شارع الملك فيصل",

"city": "الرياض",

"country": "السعودية"

}

}

}

التعشيش العميق

{

"company": {

"name": "شركة التقنية",

"departments": [

{

"name": "قسم التطوير",

"teams": [

{

"name": "فريق Frontend",

"members": [

{

"id": 1,

"name": "أحمد",

"skills": ["React", "TypeScript"],

"projects": [

{

"id": 101,

"name": "تطبيق الويب",

"tasks": [

{

"id": 1001,

"title": "تصميم الواجهة",

"assignee": {

"id": 1,

"name": "أحمد"

}

}

]

}

]

}

]

}

]

}

]

}

}

مشاكل التعشيش العميق

// صعب القراءة والصيانة

const taskTitle = data.company.departments[0]

.teams[0].members[0].projects[0].tasks[0].title;

التطبيع (Normalization)

قبل التطبيع

{

"posts": [

{

"id": 1,

"title": "مقالة 1",

"author": {

"id": 10,

"name": "أحمد",

"email": "ahmed@example.com"

},

"comments": [

{

"id": 100,

"text": "تعليق رائع",

"author": {

"id": 10,

"name": "أحمد",

"email": "ahmed@example.com"

}

}

]

}

]

}

مشكلة: تكرار بيانات المؤلف

بعد التطبيع

{

"users": {

"10": {

"id": 10,

"name": "أحمد",

"email": "ahmed@example.com"

}

},

"posts": {

"1": {

"id": 1,

"title": "مقالة 1",

"authorId": 10,

"commentIds": [100]

}

},

"comments": {

"100": {

"id": 100,

"text": "تعليق رائع",

"authorId": 10,

"postId": 1

}

}

}

مكتبة normalizr

const { normalize, schema } = require('normalizr');

// تعريف Schema

const user = new schema.Entity('users');

const comment = new schema.Entity('comments', {

author: user

});

const post = new schema.Entity('posts', {

author: user,

comments: [comment]

});

// البيانات الأصلية

const originalData = {

id: 1,

title: 'مقالة 1',

author: { id: 10, name: 'أحمد' },

comments: [

{

id: 100,

text: 'تعليق',

author: { id: 10, name: 'أحمد' }

}

]

};

// التطبيع

const normalized = normalize(originalData, post);

console.log(normalized);

أنماط التصميم

1. نمط HAL (Hypertext Application Language)

{

"_links": {

"self": { "href": "/users/123" },

"posts": { "href": "/users/123/posts" },

"followers": { "href": "/users/123/followers" }

},

"id": 123,

"name": "أحمد محمد",

"email": "ahmed@example.com"

}

2. نمط JSON:API

{

"data": {

"type": "users",

"id": "123",

"attributes": {

"name": "أحمد محمد",

"email": "ahmed@example.com"

},

"relationships": {

"posts": {

"links": {

"related": "/users/123/posts"

},

"data": [

{ "type": "posts", "id": "1" },

{ "type": "posts", "id": "2" }

]

}

}

},

"included": [

{

"type": "posts",

"id": "1",

"attributes": {

"title": "مقالة 1"

}

}

]

}

3. نمط Envelope

{

"status": "success",

"data": {

"users": [...],

"total": 100

},

"meta": {

"page": 1,

"perPage": 10,

"totalPages": 10

},

"links": {

"first": "/api/users?page=1",

"last": "/api/users?page=10",

"next": "/api/users?page=2"

}

}

4. نمط الإصدارات

{

"version": "2.0",

"data": {

"id": 123,

"name": "أحمد"

}

}

المراجع الدائرية

المشكلة

const user = {

id: 1,

name: 'أحمد'

};

const post = {

id: 100,

title: 'مقالة',

author: user

};

// مرجع دائري

user.posts = [post];

// خطأ: لا يمكن تحويل إلى JSON

JSON.stringify(user);

// TypeError: Converting circular structure to JSON

الحل 1: استخدام Replacer

function getCircularReplacer() {

const seen = new WeakSet();

return (key, value) => {

if (typeof value === 'object' && value !== null) {

if (seen.has(value)) {

return '[Circular]';

}

seen.add(value);

}

return value;

};

}

const json = JSON.stringify(user, getCircularReplacer());

الحل 2: استخدام IDs

{

"users": [

{

"id": 1,

"name": "أحمد",

"postIds": [100]

}

],

"posts": [

{

"id": 100,

"title": "مقالة",

"authorId": 1

}

]

}

الحل 3: مكتبة flatted

const { stringify, parse } = require('flatted');

const circular = { name: 'أحمد' };

circular.self = circular;

const json = stringify(circular);

const restored = parse(json);

تحسين الأداء

1. تقليل الحجم

قبل

{

"firstName": "أحمد",

"lastName": "محمد",

"emailAddress": "ahmed@example.com",

"phoneNumber": "+966501234567"

}

بعد

{

"fn": "أحمد",

"ln": "محمد",

"em": "ahmed@example.com",

"ph": "+966501234567"

}

2. الضغط

const zlib = require('zlib');

const data = JSON.stringify(largeObject);

// الضغط

zlib.gzip(data, (err, compressed) => {

console.log('الأصل:', data.length);

console.log('مضغوط:', compressed.length);

console.log('توفير:',

((1 - compressed.length / data.length) 100).toFixed(2) + '%'

);

});

3. التقسيم (Chunking)

{

"data": [...],

"pagination": {

"page": 1,

"perPage": 50,

"total": 1000,

"pages": 20

},

"links": {

"next": "/api/data?page=2"

}

}

4. الحقول الانتقائية

// طلب حقول محددة فقط

GET /api/users/123?fields=id,name,email

// الاستجابة

{

"id": 123,

"name": "أحمد",

"email": "ahmed@example.com"

}

بنيات تطبيقات حقيقية

1. E-Commerce

{

"product": {

"id": "P123",

"name": "لابتوب",

"price": {

"amount": 3000,

"currency": "SAR"

},

"variants": [

{

"id": "V1",

"name": "رمادي - 256GB",

"sku": "LAP-GRAY-256",

"price": {

"amount": 3000,

"currency": "SAR"

},

"stock": {

"quantity": 50,

"available": true

}

}

],

"images": [

{

"url": "https://example.com/image1.jpg",

"alt": "صورة اللابتوب",

"isPrimary": true

}

],

"categories": [

{

"id": "C1",

"name": "إلكترونيات",

"path": "/electronics/computers"

}

],

"specifications": {

"processor": "Intel i7",

"ram": "16GB",

"storage": "256GB SSD"

},

"reviews": {

"average": 4.5,

"count": 120,

"distribution": {

"5": 70,

"4": 30,

"3": 15,

"2": 3,

"1": 2

}

}

}

}

2. Social Media

{

"post": {

"id": "POST123",

"type": "photo",

"content": {

"text": "منظر رائع!",

"media": [

{

"type": "image",

"url": "https://example.com/photo.jpg",

"width": 1920,

"height": 1080,

"thumbnails": {

"small": "https://example.com/photo-small.jpg",

"medium": "https://example.com/photo-medium.jpg"

}

}

]

},

"author": {

"id": "USER123",

"username": "ahmed",

"displayName": "أحمد محمد",

"avatar": "https://example.com/avatar.jpg",

"verified": true

},

"engagement": {

"likes": 150,

"comments": 23,

"shares": 5,

"views": 1200

},

"interactions": {

"likedByViewer": false,

"savedByViewer": true

},

"metadata": {

"createdAt": "2024-01-15T10:30:00Z",

"updatedAt": "2024-01-15T11:00:00Z",

"location": {

"name": "الرياض",

"coordinates": {

"lat": 24.7136,

"lng": 46.6753

}

},

"hashtags": ["طبيعة", "سفر"]

}

}

}

3. Dashboard Analytics

{

"dashboard": {

"period": {

"start": "2024-01-01",

"end": "2024-01-31"

},

"summary": {

"totalRevenue": {

"value": 500000,

"change": 12.5,

"trend": "up"

},

"totalOrders": {

"value": 1250,

"change": -3.2,

"trend": "down"

}

},

"charts": {

"revenue": {

"type": "line",

"data": [

{

"date": "2024-01-01",

"value": 15000

},

{

"date": "2024-01-02",

"value": 18000

}

]

},

"topProducts": {

"type": "bar",

"data": [

{

"name": "منتج 1",

"sales": 50000,

"units": 200

}

]

}

},

"filters": {

"applied": ["region:riyadh", "category:electronics"],

"available": [

{

"name": "region",

"options": ["riyadh", "jeddah", "dammam"]

}

]

}

}

}

أمثلة برمجية متقدمة

TypeScript: Type-Safe JSON

interface User {

id: number;

name: string;

email: string;

profile?: {

bio: string;

avatar: string;

};

settings: {

notifications: boolean;

theme: 'light' | 'dark';

};

}

// دالة آمنة للأنواع

function parseUser(json: string): User {

const data = JSON.parse(json);

// التحقق من الأنواع

if (!data.id || !data.name || !data.email) {

throw new Error('بيانات غير صالحة');

}

return data as User;

}

JSON Path للبحث

const jp = require('jsonpath');

const data = {

store: {

books: [

{

title: 'كتاب 1',

price: 50,

author: 'أحمد'

},

{

title: 'كتاب 2',

price: 80,

author: 'محمد'

}

]

}

};

// البحث

const cheapBooks = jp.query(data, '$..books[?(@.price < 60)]');

console.log(cheapBooks);

// جميع الأسعار

const prices = jp.query(data, '$..price');

console.log(prices); // [50, 80]

JSON Patch للتحديثات

const jsonpatch = require('fast-json-patch');

const original = {

name: 'أحمد',

age: 25

};

const updated = {

name: 'أحمد محمد',

age: 25,

email: 'ahmed@example.com'

};

// إنشاء patch

const patch = jsonpatch.compare(original, updated);

console.log(patch);

/

[

{ op: 'replace', path: '/name', value: 'أحمد محمد' },

{ op: 'add', path: '/email', value: 'ahmed@example.com' }

]

*/

// تطبيق patch

const result = jsonpatch.applyPatch(original, patch).newDocument;

أفضل الممارسات

1. التسمية الواضحة

// سيء

{

"d": "2024-01-15",

"u": 123

}

// جيد

{

"createdAt": "2024-01-15",

"userId": 123

}

2. الثبات

// احفظ نفس البنية

{

"users": [

{ "id": 1, "name": "أحمد" },

{ "id": 2, "name": "محمد" }

]

}

3. معالجة null

{

"name": "أحمد",

"email": "ahmed@example.com",

"phone": null,

"bio": ""

}

4. التوثيق

استخدم JSON Schema لتوثيق البنية.

الملخص

البنيات المتقدمة:

  • التطبيع يقلل التكرار
  • أنماط التصميم تسهل الصيانة
  • تحسين الأداء مهم
  • اتبع أفضل الممارسات

خطط البنية جيداً من البداية!

Share:

مقالات ذات صلة

Read in English