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

JSON APIs وخدمات REST

تعلم كيفية العمل مع JSON في REST APIs. أفضل الممارسات، أمثلة، وتقنيات متقدمة.

Big JSON Team15 دقيقة للقراءةprogramming
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.

15 دقيقة قراءة

# JSON APIs وخدمات REST

JSON هو التنسيق القياسي لتبادل البيانات في REST APIs.

مقدمة

لماذا JSON مع REST؟

  • خفيف - حجم أقل من XML
  • قابل للقراءة - سهل الفهم
  • مدعوم - جميع اللغات تدعمه
  • سريع - تحليل سريع
  • معيار - معيار الصناعة

مبادئ REST

الطرق الأساسية

  • GET - قراءة البيانات
  • POST - إنشاء بيانات
  • PUT - تحديث كامل
  • PATCH - تحديث جزئي
  • DELETE - حذف البيانات

رموز الحالة

200 OK - نجاح

201 Created - تم الإنشاء

400 Bad Request - طلب خاطئ

401 Unauthorized - غير مصرح

404 Not Found - غير موجود

500 Internal Server Error - خطأ في الخادم

بنية الاستجابة

استجابة ناجحة

{

"success": true,

"data": {

"id": 1,

"الاسم": "أحمد",

"البريد": "ahmed@example.com"

},

"message": "تم بنجاح"

}

استجابة خطأ

{

"success": false,

"error": {

"code": "VALIDATION_ERROR",

"message": "البيانات غير صالحة",

"details": [

{

"field": "البريد",

"message": "البريد الإلكتروني غير صالح"

}

]

}

}

قائمة بالترقيم

{

"success": true,

"data": [

{"id": 1, "الاسم": "أحمد"},

{"id": 2, "الاسم": "فاطمة"}

],

"pagination": {

"page": 1,

"limit": 10,

"total": 100,

"pages": 10

}

}

طلبات REST

GET - قراءة

// جلب مستخدم واحد

fetch('https://api.example.com/users/1')

.then(response => response.json())

.then(data => console.log(data));

// جلب قائمة

fetch('https://api.example.com/users?page=1&limit=10')

.then(response => response.json())

.then(data => console.log(data));

POST - إنشاء

const newUser = {

الاسم: 'أحمد',

البريد: 'ahmed@example.com',

العمر: 30

};

fetch('https://api.example.com/users', {

method: 'POST',

headers: {

'Content-Type': 'application/json'

},

body: JSON.stringify(newUser)

})

.then(response => response.json())

.then(data => console.log('تم الإنشاء:', data));

PUT - تحديث كامل

const updatedUser = {

الاسم: 'أحمد محمد',

البريد: 'ahmed.new@example.com',

العمر: 31

};

fetch('https://api.example.com/users/1', {

method: 'PUT',

headers: {

'Content-Type': 'application/json'

},

body: JSON.stringify(updatedUser)

})

.then(response => response.json())

.then(data => console.log('تم التحديث:', data));

PATCH - تحديث جزئي

const partialUpdate = {

العمر: 31

};

fetch('https://api.example.com/users/1', {

method: 'PATCH',

headers: {

'Content-Type': 'application/json'

},

body: JSON.stringify(partialUpdate)

})

.then(response => response.json())

.then(data => console.log('تم التحديث:', data));

DELETE - حذف

fetch('https://api.example.com/users/1', {

method: 'DELETE'

})

.then(response => response.json())

.then(data => console.log('تم الحذف:', data));

المصادقة والترخيص

Bearer Token

const token = 'your-access-token';

fetch('https://api.example.com/users/me', {

headers: {

'Authorization': Bearer ${token},

'Content-Type': 'application/json'

}

})

.then(response => response.json())

.then(data => console.log(data));

API Key

fetch('https://api.example.com/data', {

headers: {

'X-API-Key': 'your-api-key',

'Content-Type': 'application/json'

}

})

.then(response => response.json())

.then(data => console.log(data));

معالجة الأخطاء

فحص الحالة

async function fetchUser(id) {

try {

const response = await fetch(https://api.example.com/users/${id});

if (!response.ok) {

throw new Error(HTTP error! status: ${response.status});

}

const data = await response.json();

return data;

} catch (error) {

console.error('خطأ:', error.message);

throw error;

}

}

معالجة شاملة

async function apiRequest(url, options = {}) {

try {

const response = await fetch(url, {

...options,

headers: {

'Content-Type': 'application/json',

...options.headers

}

});

const data = await response.json();

if (!response.ok) {

throw new Error(data.error?.message || 'حدث خطأ');

}

return data;

} catch (error) {

if (error.name === 'TypeError') {

throw new Error('خطأ في الاتصال بالخادم');

}

throw error;

}

}

// الاستخدام

try {

const user = await apiRequest('https://api.example.com/users/1');

console.log(user);

} catch (error) {

console.error('فشل الطلب:', error.message);

}

إنشاء REST API

Express.js

const express = require('express');

const app = express();

app.use(express.json());

// GET - جلب جميع المستخدمين

app.get('/api/users', (req, res) => {

const users = [

{ id: 1, الاسم: 'أحمد' },

{ id: 2, الاسم: 'فاطمة' }

];

res.json({

success: true,

data: users

});

});

// GET - جلب مستخدم واحد

app.get('/api/users/:id', (req, res) => {

const id = parseInt(req.params.id);

const user = { id, الاسم: 'أحمد' };

res.json({

success: true,

data: user

});

});

// POST - إنشاء مستخدم

app.post('/api/users', (req, res) => {

const newUser = req.body;

// التحقق من البيانات

if (!newUser.الاسم) {

return res.status(400).json({

success: false,

error: {

message: 'الاسم مطلوب'

}

});

}

// إنشاء المستخدم

const created = { id: 3, ...newUser };

res.status(201).json({

success: true,

data: created

});

});

// PUT - تحديث مستخدم

app.put('/api/users/:id', (req, res) => {

const id = parseInt(req.params.id);

const updated = { id, ...req.body };

res.json({

success: true,

data: updated

});

});

// DELETE - حذف مستخدم

app.delete('/api/users/:id', (req, res) => {

const id = parseInt(req.params.id);

res.json({

success: true,

message: 'تم الحذف بنجاح'

});

});

app.listen(3000, () => {

console.log('Server running on port 3000');

});

مع التحقق

const express = require('express');

const Ajv = require('ajv');

const app = express();

const ajv = new Ajv();

app.use(express.json());

// مخطط التحقق

const userSchema = {

type: 'object',

properties: {

الاسم: { type: 'string', minLength: 2 },

البريد: { type: 'string', format: 'email' },

العمر: { type: 'number', minimum: 18 }

},

required: ['الاسم', 'البريد']

};

const validateUser = ajv.compile(userSchema);

app.post('/api/users', (req, res) => {

if (!validateUser(req.body)) {

return res.status(400).json({

success: false,

error: {

message: 'بيانات غير صالحة',

details: validateUser.errors

}

});

}

// إنشاء المستخدم

res.status(201).json({

success: true,

data: req.body

});

});

Python Flask

from flask import Flask, request, jsonify

app = Flask(__name__)

users = [

{'id': 1, 'الاسم': 'أحمد'},

{'id': 2, 'الاسم': 'فاطمة'}

]

@app.route('/api/users', methods=['GET'])

def get_users():

return jsonify({

'success': True,

'data': users

})

@app.route('/api/users/<int:user_id>', methods=['GET'])

def get_user(user_id):

user = next((u for u in users if u['id'] == user_id), None)

if user is None:

return jsonify({

'success': False,

'error': {'message': 'المستخدم غير موجود'}

}), 404

return jsonify({

'success': True,

'data': user

})

@app.route('/api/users', methods=['POST'])

def create_user():

data = request.get_json()

if not data.get('الاسم'):

return jsonify({

'success': False,

'error': {'message': 'الاسم مطلوب'}

}), 400

new_user = {

'id': len(users) + 1,

*data

}

users.append(new_user)

return jsonify({

'success': True,

'data': new_user

}), 201

if __name__ == '__main__':

app.run(debug=True)

ميزات متقدمة

الترقيم (Pagination)

app.get('/api/users', (req, res) => {

const page = parseInt(req.query.page) || 1;

const limit = parseInt(req.query.limit) || 10;

const offset = (page - 1) limit;

// جلب البيانات (مثال)

const total = 100;

const users = []; // البيانات المرقمة

res.json({

success: true,

data: users,

pagination: {

page,

limit,

total,

pages: Math.ceil(total / limit)

}

});

});

البحث والتصفية

app.get('/api/users', (req, res) => {

const { search, age, city } = req.query;

let users = getAllUsers(); // جلب جميع المستخدمين

// تطبيق التصفية

if (search) {

users = users.filter(u =>

u.الاسم.includes(search)

);

}

if (age) {

users = users.filter(u => u.العمر === parseInt(age));

}

if (city) {

users = users.filter(u => u.المدينة === city);

}

res.json({

success: true,

data: users,

filters: { search, age, city }

});

});

الترتيب

app.get('/api/users', (req, res) => {

const { sortBy, order } = req.query;

let users = getAllUsers();

if (sortBy) {

users.sort((a, b) => {

const aVal = a[sortBy];

const bVal = b[sortBy];

if (order === 'desc') {

return bVal > aVal ? 1 : -1;

}

return aVal > bVal ? 1 : -1;

});

}

res.json({

success: true,

data: users

});

});

التخزين المؤقت

const cache = new Map();

app.get('/api/users/:id', async (req, res) => {

const id = req.params.id;

const cacheKey = user_${id};

// فحص التخزين المؤقت

if (cache.has(cacheKey)) {

return res.json({

success: true,

data: cache.get(cacheKey),

cached: true

});

}

// جلب من قاعدة البيانات

const user = await getUserById(id);

// حفظ في التخزين المؤقت

cache.set(cacheKey, user);

res.json({

success: true,

data: user,

cached: false

});

});

تحديد الطلبات (Rate Limiting)

const rateLimit = require('express-rate-limit');

const limiter = rateLimit({

windowMs: 15 60 1000, // 15 دقيقة

max: 100, // حد أقصى 100 طلب

message: {

success: false,

error: {

message: 'تجاوزت الحد الأقصى للطلبات'

}

}

});

app.use('/api/', limiter);

CORS

const cors = require('cors');

// السماح لجميع المصادر

app.use(cors());

// تخصيص CORS

app.use(cors({

origin: 'https://example.com',

methods: ['GET', 'POST', 'PUT', 'DELETE'],

allowedHeaders: ['Content-Type', 'Authorization']

}));

أمثلة API حقيقية

جلب بيانات الطقس

async function getWeather(city) {

const apiKey = 'your-api-key';

const url = https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apiKey};

const response = await fetch(url);

const data = await response.json();

return {

المدينة: data.name,

الحرارة: data.main.temp,

الوصف: data.weather[0].description

};

}

استخدام GitHub API

async function getGitHubUser(username) {

const response = await fetch(https://api.github.com/users/${username});

const data = await response.json();

return {

الاسم: data.name,

المستودعات: data.public_repos,

المتابعون: data.followers

};

}

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

1. استخدم HTTPS

جميع الطلبات يجب أن تكون عبر HTTPS.

2. نسخ API

app.use('/api/v1/users', usersRouter);

app.use('/api/v2/users', usersV2Router);

3. استجابات متسقة

احتفظ ببنية استجابة موحدة:

{

"success": true/false,

"data": {},

"error": {},

"meta": {}

}

4. استخدم رموز الحالة الصحيحة

  • 200: نجاح
  • 201: تم الإنشاء
  • 400: خطأ في الطلب
  • 401: غير مصرح
  • 404: غير موجود
  • 500: خطأ في الخادم

5. التحقق من البيانات

تحقق دائماً من البيانات الواردة.

6. معالجة الأخطاء

app.use((err, req, res, next) => {

console.error(err.stack);

res.status(500).json({

success: false,

error: {

message: 'حدث خطأ في الخادم'

}

});

});

الملخص

JSON APIs و REST:

  • معيار الصناعة
  • سهل التطوير
  • مدعوم جيداً
  • مرن وقابل للتوسع

ابنِ APIs قوية وموثوقة!

Share:

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

Read in English