APIs: الدليل الشامل لبناء واستهلاك REST و GraphQL APIs مع أمثلة كود عملية في 2026

APIs: الدليل الشامل لبناء واستهلاك REST و GraphQL APIs مع أمثلة كود عملية في 2026

Getting your Trinity Audio player ready... APIs: الدليل الشامل لبناء واستهلاك REST و GraphQL APIs مع أمثلة كود عملية في مقتطف المقال: APIs (Application Programming Interfaces) هي العمود الفقري للتطبيقات الحديثة. بدونها، لا يمكن للتطبيقات التواصل مع بعضها البعض. في...

حجم الخط:
Getting your Trinity Audio player ready...

APIs: الدليل الشامل لبناء واستهلاك REST و GraphQL APIs مع أمثلة كود عملية في 2026

مقتطف المقال:
APIs (Application Programming Interfaces) هي العمود الفقري للتطبيقات الحديثة. بدونها، لا يمكن للتطبيقات التواصل مع بعضها البعض. في هذا الدليل الشامل، ستتعلم كل شيء عن APIs: من REST الأشهر، إلى GraphQL الأحدث، كيفية بناء API احترافي، كيفية استهلاكه، المصادقة والأمان، مع أمثلة كود عملية باستخدام Node.js و Express.

ما هي APIs ولماذا مهمة؟

API (Application Programming Interface) هو مجموعة من القواعد والبروتوكولات التي تسمح للتطبيقات بالتواصل مع بعضها البعض. هو الوسيط الذي يسمح لتطبيقين مختلفين بالتحدث مع بعضهما.

🔌 التكامل: ربط التطبيقات ببعضها
⚡ الكفاءة: إعادة استخدام الكود
🔒 الأمان: التحكم في الوصول
🌐 التوسع: بناء أنظمة قابلة للتوسع

💡 أمثلة على استخدام APIs في الحياة اليومية

  • خرائط جوجل: تطبيقات تستخدم API خرائط جوجل
  • الدفع الإلكتروني: Stripe, PayPal APIs
  • وسائل التواصل: Facebook, Twitter APIs
  • الطقس: Weather APIs
  • البريد الإلكتروني: SendGrid, Mailgun APIs

أنواع APIs

⚖️ مقارنة شاملة: REST vs GraphQL vs SOAP

المعيار REST GraphQL SOAP
البروتوكول HTTP HTTP HTTP/SMTP
صيغة البيانات JSON JSON XML
المرونة ⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐
الأداء ⭐⭐⭐⭐ ⭐⭐⭐⭐⭐ ⭐⭐⭐
سهولة التعلم ⭐⭐⭐⭐⭐ ⭐⭐⭐ ⭐⭐
الشعبية ⭐⭐⭐⭐⭐ ⭐⭐⭐⭐ ⭐⭐
الاستخدام الأمثل معظم التطبيقات تطبيقات معقدة أنظمة قديمة

REST API: الأشهر والأكثر استخداماً

🌐 ما هو REST API؟

REST (Representational State Transfer) هو نمط معماري لبناء APIs. يستخدم بروتوكول HTTP ويعتمد على الموارد (Resources) والعمليات (Operations).

مبادئ REST:

  1. Client-Server: فصل الواجهة عن الخادم
  2. Stateless: كل طلب مستقل
  3. Cacheable: الاستجابات قابلة للتخزين المؤقت
  4. Uniform Interface: واجهة موحدة
  5. Layered System: نظام طبقي

🌐 HTTP Methods في REST

Method العملية مثال Idempotent
GET جلب البيانات GET /users ✅ نعم
POST إنشاء مورد جديد POST /users ❌ لا
PUT تحديث مورد (كامل) PUT /users/1 ✅ نعم
PATCH تحديث جزئي PATCH /users/1 ❌ لا
DELETE حذف مورد DELETE /users/1 ✅ نعم

بناء REST API مع Node.js و Express

🛠️ إعداد المشروع

# إنشاء المشروع
mkdir my-api
cd my-api
npm init -y

# تثبيت المكتبات
npm install express mongoose cors dotenv bcryptjs jsonwebtoken
npm install --save-dev nodemon

# هيكل المشروع
my-api/
├── src/
│   ├── controllers/
│   ├── models/
│   ├── routes/
│   ├── middleware/
│   ├── config/
│   └── app.js
├── .env
├── package.json
└── server.js

🛠️ بناء API كامل

// server.js
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();

const app = express();

// Middleware
app.use(cors());
app.use(express.json());

// Connect to MongoDB
mongoose.connect(process.env.MONGODB_URI)
    .then(() => console.log('MongoDB connected'))
    .catch(err => console.error(err));

// Routes
app.use('/api/users', require('./routes/users'));
app.use('/api/products', require('./routes/products'));

// Error handling
app.use((err, req, res, next) => {
    res.status(err.status || 500).json({
        error: err.message || 'Internal Server Error'
    });
});

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));

🛠️ Model (User Model)

// models/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');

const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: [true, 'Name is required'],
        trim: true
    },
    email: {
        type: String,
        required: [true, 'Email is required'],
        unique: true,
        lowercase: true
    },
    password: {
        type: String,
        required: [true, 'Password is required'],
        minlength: 6
    },
    role: {
        type: String,
        enum: ['user', 'admin'],
        default: 'user'
    }
}, {
    timestamps: true
});

// Hash password before saving
userSchema.pre('save', async function(next) {
    if (!this.isModified('password')) return next();
    this.password = await bcrypt.hash(this.password, 10);
    next();
});

// Compare password method
userSchema.methods.comparePassword = async function(candidatePassword) {
    return await bcrypt.compare(candidatePassword, this.password);
};

module.exports = mongoose.model('User', userSchema);

🛠️ Controller (Users Controller)

// controllers/usersController.js
const User = require('../models/User');
const jwt = require('jsonwebtoken');

// @desc    Register user
// @route   POST /api/users/register
exports.register = async (req, res) => {
    try {
        const { name, email, password } = req.body;
        
        // Check if user exists
        const existingUser = await User.findOne({ email });
        if (existingUser) {
            return res.status(400).json({ 
                error: 'User already exists' 
            });
        }
        
        // Create user
        const user = await User.create({ name, email, password });
        
        // Generate token
        const token = jwt.sign(
            { id: user._id },
            process.env.JWT_SECRET,
            { expiresIn: '30d' }
        );
        
        res.status(201).json({
            success: true,
            token,
            user: {
                id: user._id,
                name: user.name,
                email: user.email
            }
        });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
};

// @desc    Login user
// @route   POST /api/users/login
exports.login = async (req, res) => {
    try {
        const { email, password } = req.body;
        
        // Find user
        const user = await User.findOne({ email }).select('+password');
        if (!user) {
            return res.status(401).json({ 
                error: 'Invalid credentials' 
            });
        }
        
        // Check password
        const isMatch = await user.comparePassword(password);
        if (!isMatch) {
            return res.status(401).json({ 
                error: 'Invalid credentials' 
            });
        }
        
        // Generate token
        const token = jwt.sign(
            { id: user._id },
            process.env.JWT_SECRET,
            { expiresIn: '30d' }
        );
        
        res.json({
            success: true,
            token,
            user: {
                id: user._id,
                name: user.name,
                email: user.email
            }
        });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
};

// @desc    Get all users
// @route   GET /api/users
exports.getUsers = async (req, res) => {
    try {
        const users = await User.find();
        res.json({ success: true, data: users });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
};

// @desc    Get user by ID
// @route   GET /api/users/:id
exports.getUser = async (req, res) => {
    try {
        const user = await User.findById(req.params.id);
        if (!user) {
            return res.status(404).json({ 
                error: 'User not found' 
            });
        }
        res.json({ success: true, data: user });
    } catch (error) {
        res.status(500).json({ error: error.message });
    }
};

🛠️ Routes

// routes/users.js
const express = require('express');
const router = express.Router();
const { protect } = require('../middleware/auth');

const {
    register,
    login,
    getUsers,
    getUser
} = require('../controllers/usersController');

router.post('/register', register);
router.post('/login', login);
router.get('/', protect, getUsers);
router.get('/:id', protect, getUser);

module.exports = router;

🛠️ Auth Middleware

// middleware/auth.js
const jwt = require('jsonwebtoken');
const User = require('../models/User');

exports.protect = async (req, res, next) => {
    let token;
    
    // Check for token
    if (req.headers.authorization && 
        req.headers.authorization.startsWith('Bearer')) {
        token = req.headers.authorization.split(' ')[1];
    }
    
    if (!token) {
        return res.status(401).json({ 
            error: 'Not authorized' 
        });
    }
    
    try {
        // Verify token
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        
        // Get user
        req.user = await User.findById(decoded.id);
        
        next();
    } catch (error) {
        res.status(401).json({ 
            error: 'Not authorized' 
        });
    }
};

استهلاك API من Frontend

🌐 استهلاك API مع Fetch API

// Register User
const registerUser = async (name, email, password) => {
    try {
        const response = await fetch('http://localhost:5000/api/users/register', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ name, email, password })
        });
        
        const data = await response.json();
        
        if (!response.ok) {
            throw new Error(data.error);
        }
        
        // Store token
        localStorage.setItem('token', data.token);
        
        return data;
    } catch (error) {
        console.error('Error:', error);
    }
};

// Login User
const loginUser = async (email, password) => {
    try {
        const response = await fetch('http://localhost:5000/api/users/login', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ email, password })
        });
        
        const data = await response.json();
        
        if (!response.ok) {
            throw new Error(data.error);
        }
        
        localStorage.setItem('token', data.token);
        
        return data;
    } catch (error) {
        console.error('Error:', error);
    }
};

// Get Users (Protected)
const getUsers = async () => {
    try {
        const token = localStorage.getItem('token');
        
        const response = await fetch('http://localhost:5000/api/users', {
            headers: {
                'Authorization': `Bearer ${token}`
            }
        });
        
        const data = await response.json();
        
        return data;
    } catch (error) {
        console.error('Error:', error);
    }
};

🌐 استهلاك API مع Axios

// Install Axios
npm install axios

// Create Axios instance
import axios from 'axios';

const api = axios.create({
    baseURL: 'http://localhost:5000/api',
    headers: {
        'Content-Type': 'application/json'
    }
});

// Add token interceptor
api.interceptors.request.use(
    (config) => {
        const token = localStorage.getItem('token');
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

// API calls
export const registerUser = (data) => api.post('/users/register', data);
export const loginUser = (data) => api.post('/users/login', data);
export const getUsers = () => api.get('/users');
export const getUser = (id) => api.get(`/users/${id}`);

// Usage in React component
import { getUsers } from './api';

function UsersList() {
    const [users, setUsers] = useState([]);
    
    useEffect(() => {
        fetchUsers();
    }, []);
    
    const fetchUsers = async () => {
        try {
            const response = await getUsers();
            setUsers(response.data.data);
        } catch (error) {
            console.error(error);
        }
    };
    
    return (
        <div>
            {users.map(user => (
                <div key={user.id}>{user.name}</div>
            ))}
        </div>
    );
}

GraphQL: البديل الحديث

🌐 ما هو GraphQL؟

GraphQL هي لغة استعلام للـ APIs طورتها Facebook. تسمح للعميل بطلب بالضبط ما يحتاجه، لا أكثر ولا أقل.

مميزات GraphQL:

  • Ask for what you need: لا over-fetching أو under-fetching
  • Get what you ask: تحصل بالضبط على ما طلبت
  • Single endpoint: endpoint واحد لكل العمليات
  • Strong typing: نظام أنواع قوي
  • Introspection: يمكن الاستعلام عن الـ API نفسه

🌐 بناء GraphQL API

# Install dependencies
npm install @apollo/server graphql @apollo/server-plugins

فريق محتوى الصقر

فريق متخصص في تقديم محتوى عالي الجودة يركز على التسويق الرقمي وتطوير الأعمال. نسعى لتقديم معلومات قيمة ومفيدة تساعدك على تحقيق أهدافك.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *