AzLearn

بناء JSON API بـ Flask

Building a JSON API with Flask

تطبيق ~25 دقيقة

بناء JSON API بـ Flask — Building a JSON API with Flask

الخادم الذي يُعيد نصاً عادياً مفيد، لكن الإنترنت الحديث يتحدث JSON. كل تطبيق موبايل، كل موقع React، كل خدمة تحتاج بيانات — كلها تتوقع JSON. في هذا الدرس، ستبني API حقيقي يستقبل JSON ويُعيد JSON، باتباع أنماط REST المعتمدة في الصناعة.

مفهوم REST

REST (Representational State Transfer) ليس بروتوكولاً بل مجموعة مبادئ تصميم لـ APIs:

الأسلوبالمسارالعملية
GET/booksاقرأ قائمة الكتب
GET/books/1اقرأ كتاباً واحداً
POST/booksأنشئ كتاباً جديداً
PUT/books/1حدّث كتاباً كاملاً
DELETE/books/1احذف كتاباً

هذا النمط متفق عليه عالمياً — أي مطور يفهمه فور رؤيته.

jsonify — تحويل Python إلى JSON

دالة jsonify تُحوّل أي dict أو list إلى استجابة HTTP بصيغة JSON مع الترويسات الصحيحة تلقائياً:

from flask import Flask, jsonify

app = Flask(__name__)

@app.route("/api/version")
def version():
    return jsonify({
        "version": "1.0.0",
        "name": "كتبي API"
    })
# الاستجابة: {"version": "1.0.0", "name": "كتبي API"}
# مع Content-Type: application/json

request.get_json() — قراءة JSON من الطلب

عندما يُرسل العميل بيانات JSON في جسم الطلب، request.get_json() يحوّلها إلى dict:

from flask import Flask, request, jsonify

@app.route("/api/books", methods=["POST"])
def create_book():
    data = request.get_json()   # تحويل JSON إلى dict — JSON to dict
    if not data:
        return jsonify({"error": "بيانات مطلوبة"}), 400
    
    title = data.get("title")
    author = data.get("author")
    # ... حفظ الكتاب — save the book

بناء API الكتب — خطوة بخطوة

سنبني API كاملاً لإدارة مكتبة. سنبدأ بالهيكل الأساسي ونضيف عليه تدريجياً.

الخطوة 1: هيكل البيانات والمسار الأول

main.go

الخطوة 2: مسار كتاب واحد مع معالجة الخطأ

main.go

الخطوة 3: إنشاء كتاب جديد (POST)

استقبال JSON من الطلب يتطلب أن يُرسل العميل Content-Type: application/json في الترويسة. مع test_client، نستخدم content_type="application/json":

main.go

الخطوة 4: حذف كتاب (DELETE)

main.go

استجابات الخطأ الموحدة

في APIs الاحترافية، جميع الأخطاء تتبع نفس الشكل:

# شكل الخطأ الموحد — Unified error shape
def error_response(message, code):
    return jsonify({
        "error": message,
        "code": code
    }), code

# الاستخدام — Usage
return error_response("المورد غير موجود", 404)
return error_response("بيانات غير صالحة", 400)
return error_response("غير مصرح", 401)

هذا يجعل العملاء (تطبيقات الموبايل، الويب) يعرفون دائماً أين يجدون رسالة الخطأ.

التحديات التطبيقية

الآن حان وقت البناء المستقل. هذه التحديات تبني API للكتب تدريجياً — كل تحدٍّ يُضيف ميزة جديدة.

تحدي — Challenge
تحدي — Challenge
تحدي — Challenge
تحدي — Challenge