التحقق من البيانات ومعالجة أخطاء API

التحقق من البيانات ومعالجة أخطاء API

49 دقيقة
٢١ يونيو ٢٠٢٦
المرحلة 1 من 6

مقدمة: لماذا نحتاج التحقق من البيانات ومعالجة الأخطاء؟

الفصل الأول: مقدمة: لماذا التحقق من البيانات ومعالجة الأخطاء؟

مرحباً بك في الدرس الثامن عشر من سلسلة تعلم بايثون وبناء API عملي. في الدروس السابقة، قمنا ببناء API لإدارة المهام، وربطناه بقاعدة بيانات SQLite، وتعلمنا كيفية إنشاء نقاط النهاية (Endpoints) لإضافة وعرض وتحديث وحذف المهام. لكن هل لاحظت شيئاً؟ ماذا يحدث إذا أرسل المستخدم بيانات غير صحيحة؟ مثلاً، إذا أرسل اسم مهمة فارغاً، أو أرسل نصاً في حقل مخصص للأرقام؟ أو إذا حاول حذف مهمة غير موجودة؟

هنا يأتي دور التحقق من البيانات (Validation) ومعالجة الأخطاء (Error Handling). بدون هذه الأدوات، سيكون API الخاص بك ضعيفاً وغير موثوق. قد يتعطل التطبيق، أو يرسل رسائل خطأ غير مفهومة للمستخدم، أو الأسوأ من ذلك، قد يسمح بتخزين بيانات تالفة في قاعدة البيانات.

في هذا الدرس، سنتعلم كيف نجعل API الخاص بنا ذكياً وقوياً. سنستخدم أدوات FastAPI المدمجة للتحقق من صحة البيانات التي يرسلها المستخدم، وسنقوم بمعالجة الأخطاء بطريقة احترافية ترسل للمستخدم رسائل واضحة ومفيدة بدلاً من رسائل الخطأ التقنية المعقدة.

لماذا نحتاج إلى التحقق من البيانات (Validation)؟

التحقق من البيانات هو عملية التأكد من أن البيانات التي يرسلها المستخدم (أو أي مصدر خارجي) تتوافق مع القواعد التي نحددها. تخيل أن لديك نموذج تسجيل في موقع ويب. يجب أن تتأكد من أن:

  • حقل البريد الإلكتروني يحتوي على عنوان بريد إلكتروني صحيح.
  • حقل كلمة المرور لا يقل عن 8 أحرف.
  • حقل العمر يحتوي على رقم وليس نصاً.

بدون التحقق من البيانات، قد يقوم المستخدم بإدخال بيانات خاطئة تؤدي إلى أعطال في التطبيق أو ثغرات أمنية.

لماذا نحتاج إلى معالجة الأخطاء (Error Handling)؟

حتى مع أفضل التحقق من البيانات، يمكن أن تحدث أخطاء. مثلاً، قد يتعطل الاتصال بقاعدة البيانات، أو قد يحاول المستخدم الوصول إلى مورد غير موجود. معالجة الأخطاء هي عملية توقع هذه الأخطاء والتعامل معها بطريقة منظمة. بدلاً من أن ينهار التطبيق ويعرض رسالة خطأ تقنية (مثل "500 Internal Server Error")، يمكننا إرسال رسالة خطأ مخصصة وواضحة للمستخدم، مثل "عذراً، المهمة التي تبحث عنها غير موجودة".

كيف يعمل التحقق من البيانات في FastAPI؟

في FastAPI، يتم التحقق من البيانات بشكل تلقائي باستخدام مكتبة Pydantic. عندما نحدد نموذج بيانات (Model) باستخدام Pydantic، فإن FastAPI يقوم تلقائياً بالتحقق من أن البيانات المرسلة تتطابق مع النموذج. إذا كانت البيانات غير صحيحة، يقوم FastAPI بإرجاع خطأ 422 (Unprocessable Entity) مع رسالة توضح المشكلة بالضبط.

لنأخذ مثالاً عملياً. في الدرس السابق، كان لدينا نموذج للمهمة (Task) يبدو كالتالي:

from pydantic import BaseModel

class TaskCreate(BaseModel):
    title: str
    description: str | None = None
    completed: bool = False

هذا النموذج يخبر FastAPI أن حقل title يجب أن يكون نصاً (str) وهو إلزامي. حقل description يمكن أن يكون نصاً أو قيمة فارغة (None)، وحقل completed يجب أن يكون قيمة منطقية (bool) وقيمته الافتراضية False.

إذا حاول المستخدم إرسال طلب لإنشاء مهمة بدون حقل title، أو أرسل رقماً في حقل completed، فسيقوم FastAPI تلقائياً برفض الطلب وإرجاع خطأ 422 مع تفاصيل المشكلة.

معالجة الأخطاء المخصصة (Custom Error Handling)

بالإضافة إلى التحقق التلقائي، يمكننا إنشاء معالجات أخطاء مخصصة للتعامل مع حالات معينة. مثلاً، عندما يحاول المستخدم حذف مهمة غير موجودة، يجب أن نعيد خطأ 404 (Not Found) مع رسالة واضحة.

لنقم بإنشاء دالة معالجة خطأ مخصصة لهذه الحالة. سنستخدم الدالة HTTPException من FastAPI.

from fastapi import FastAPI, HTTPException

app = FastAPI()

# ... (باقي الكود)

@app.delete("/tasks/{task_id}")
def delete_task(task_id: int):
    # محاكاة البحث عن المهمة في قاعدة البيانات
    task = find_task_by_id(task_id)  # هذه دالة وهمية
    if task is None:
        # إذا لم يتم العثور على المهمة، نرفع استثناء HTTP
        raise HTTPException(status_code=404, detail="المهمة غير موجودة")
    # ... (باقي كود الحذف)
    return {"message": "تم حذف المهمة بنجاح"}

في هذا المثال، إذا لم يتم العثور على المهمة، نستخدم raise HTTPException لإرجاع استجابة خطأ برقم 404 ورسالة "المهمة غير موجودة". هذا أفضل بكثير من ترك التطبيق يتعطل أو إرجاع خطأ عام.

أمثلة عملية على التحقق من البيانات المتقدم

يمكننا إضافة المزيد من قواعد التحقق باستخدام Pydantic. على سبيل المثال، يمكننا التأكد من أن عنوان المهمة لا يقل عن 3 أحرف باستخدام Field.

from pydantic import BaseModel, Field

class TaskCreate(BaseModel):
    title: str = Field(..., min_length=3, max_length=100, description="عنوان المهمة")
    description: str | None = Field(None, max_length=500, description="وصف المهمة")
    completed: bool = False

الآن، إذا حاول المستخدم إرسال عنوان مكون من حرفين فقط، سيرفض FastAPI الطلب تلقائياً ويخبره أن العنوان يجب أن يكون على الأقل 3 أحرف.

أخطاء شائعة وكيفية تجنبها

  • عدم التحقق من وجود المورد: دائماً تحقق من وجود المورد (مثل مهمة) قبل محاولة تعديله أو حذفه. استخدم HTTPException مع الرمز 404.
  • إرجاع أخطاء عامة: لا تكتفِ بإرجاع "حدث خطأ". قدم رسالة واضحة ومحددة تساعد المستخدم على فهم المشكلة.
  • نسيان التحقق من أنواع البيانات: استخدم Pydantic لتحديد أنواع الحقول بدقة (str, int, bool, إلخ). هذا يمنع العديد من الأخطاء.
  • عدم استخدام الرموز الصحيحة: استخدم رموز HTTP الصحيحة: 400 (Bad Request) للبيانات غير الصالحة، 404 (Not Found) للموارد المفقودة، 422 (Unprocessable Entity) لأخطاء التحقق من الصحة.

تمرين صغير

الآن حان دورك للتطبيق. لديك API بسيط يدير قائمة من الكتب. كل كتاب له id (رقم صحيح) و title (نص) و author (نص).

  1. قم بإنشاء نموذج Pydantic لإنشاء كتاب جديد (BookCreate) بحيث يكون حقل title إلزامياً وألا يقل عن حرفين.
  2. قم بإنشاء نقطة نهاية (GET /books/{book_id}) تعيد تفاصيل الكتاب. إذا لم يتم العثور على الكتاب، قم بإرجاع خطأ 404 مع رسالة "الكتاب غير موجود".
  3. قم بإنشاء نقطة نهاية (POST /books) تقبل بيانات BookCreate وتضيف الكتاب إلى القائمة (يمكنك استخدام قائمة بسيطة في الذاكرة).

حاول كتابة الكود بنفسك، ثم قارنه مع الحل في نهاية الدرس القادم. هذا التمرين سيساعدك على ترسيخ المفاهيم التي تعلمتها اليوم.

نصيحة عملية: عند بناء API حقيقي، اجعل التحقق من البيانات ومعالجة الأخطاء جزءاً أساسياً من تصميمك منذ البداية. لا تتركها إلى النهاية. هذا سيوفر عليك الكثير من الوقت والجهد في المستقبل، وسيجعل API الخاص بك أكثر احترافية وأسهل في الاستخدام.

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