JSON APIs وخدمات REST
تعلم كيفية العمل مع JSON في REST APIs. أفضل الممارسات، أمثلة، وتقنيات متقدمة.
Big JSON Team
• Technical WriterExpert in JSON data manipulation, API development, and web technologies. Passionate about creating tools that make developers' lives easier.
# 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 قوية وموثوقة!
مقالات ذات صلة
Python و JSON: دليل شامل
تعلم كيفية العمل مع JSON في Python. القراءة، الكتابة، التحليل، والتحويل مع أمثلة عملية.
JavaScript و JSON: الدليل الكامل
تعلم كيفية العمل مع JSON في JavaScript. JSON.parse، JSON.stringify، وأفضل الممارسات.
رموز الويب JSON (JWT): دليل شامل
تعلم كل شيء عن JWT. البنية، الاستخدام، الأمان، وأفضل الممارسات مع أمثلة عملية.