انتقل إلى المحتوى الرئيسي

TP3.2 — تطبيق CRUD كامل (وضع مستقل)

تحدي مستقل

هذا التمرين يستند إلى نفس التمرين تمامًا كما في TP3.1، ولكن بدون أي كود مقدم. يجب عليك تنفيذ كل شيء بنفسك. إذا واجهت صعوبة، استشر TP3.1 كمرجع.

المدة المقدرة: 2 إلى 3 ساعات

المتطلبات المسبقة: فهم مفاهيم الوحدة 3 (العمارة الطبقية، Spring Data JPA، API REST)


السياق​

أنت مطور backend في مدرسة. طُلب منك إنشاء API REST لإدارة الطلاب باستخدام Spring Boot.


ما يجب عليك تسليمه​

الخطوة 1 — إنشاء مشروع Spring Boot​

  • أنشئ مشروع Spring Boot جديد عبر Spring Initializr
  • اختر التبعيات اللازمة لـ:
    • إنشاء API REST
    • استخدام قاعدة بيانات في الذاكرة (H2)
    • تنفيذ الاستمرارية JPA
    • التحقق من صحة البيانات المدخلة

الخطوة 2 — إنشاء الكيان Student​

أنشئ كيان Student مع الحقول التالية:

الحقلالنوعالقيود
idLongمفتاح أساسي، يتم توليده تلقائيًا
firstNameStringإلزامي، بين 2 و50 حرفًا
lastNameStringإلزامي، بين 2 و50 حرفًا
emailStringإلزامي، بصيغة بريد إلكتروني صحيحة، فريد
ageIntegerإلزامي، بين 18 و100
programStringإلزامي (مثال: "علوم الحاسوب"، "هندسة البرمجيات")

الخطوة 3 — إنشاء Repository​

  • أنشئ واجهة Repository للكيان Student
  • أضف طريقة للتحقق مما إذا كان البريد الإلكتروني موجودًا بالفعل
  • أضف طريقة للبحث عن الطلاب حسب البرنامج

الخطوة 4 — إنشاء الخدمة​

أنشئ خدمة تنفذ المنطق التجاري التالي:

  • استرجاع جميع الطلاب
  • استرجاع طالب حسب معرفه — إذا لم يكن الطالب موجودًا، أطلق استثناء مناسب
  • إنشاء طالب — تحقق من أن البريد الإلكتروني غير مستخدم بالفعل قبل الحفظ. إذا كان البريد الإلكتروني موجودًا بالفعل، أعد خطأ 409 (Conflict)
  • تعديل طالب — تحقق من أن الطالب موجود، ثم قم بتحديث معلوماته
  • حذف طالب — تحقق من أن الطالب موجود، ثم قم بحذفه

الخطوة 5 — إنشاء Controller REST​

أنشئ Controller يعرض النقاط النهائية التالية:

طريقة HTTPURLالإجراءكود الإرجاع المتوقع
GET/api/studentsقائمة بجميع الطلاب200 OK
GET/api/students/\{id\}تفاصيل طالب200 OK أو 404 Not Found
POST/api/studentsإنشاء طالب201 Created أو 409 Conflict
PUT/api/students/\{id\}تعديل طالب200 OK أو 404 Not Found
DELETE/api/students/\{id\}حذف طالب204 No Content أو 404 Not Found
  • يجب أن يتم التحقق تلقائيًا من البيانات المرسلة في POST وPUT
  • إذا فشل التحقق، أعد كود 400 Bad Request

الخطوة 6 — تكوين قاعدة بيانات H2​

  • قم بتكوين التطبيق لاستخدام قاعدة بيانات H2 في الذاكرة
  • فعّل وحدة التحكم H2 لتمكين عرض البيانات في المتصفح
  • يجب أن تكون وحدة التحكم متاحة على URL /h2-console

الخطوة 7 — اختبار جميع النقاط النهائية​

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

  1. إنشاء 3 طلاب (POST) — تحقق من الكود 201
  2. قائمة بجميع الطلاب (GET) — تحقق من وجود 3
  3. استرجاع طالب حسب معرفه (GET) — تحقق من البيانات
  4. تعديل طالب (PUT) — تغيير برنامجه، تحقق من التحديث
  5. حذف طالب (DELETE) — تحقق من الكود 204
  6. إعادة قائمة بجميع الطلاب — تحقق من بقاء 2 فقط
  7. اختبار الأخطاء:
    • GET على معرف غير موجود → 404
    • POST مع بريد إلكتروني مستخدم بالفعل → 409
    • POST مع بريد إلكتروني غير صالح → 400
    • POST مع اسم أول فارغ → 400

تمارين إضافية​

إضافة 1 — البحث حسب البرنامج​

أضف نقطة نهاية تتيح البحث عن الطلاب حسب البرنامج:

GET /api/students/program/{program}

على سبيل المثال: GET /api/students/program/Informatique يعيد جميع الطلاب في علوم الحاسوب.


إضافة 2 — إحصائيات​

أضف نقطة نهاية تعيد الإحصائيات:

GET /api/students/stats

يجب أن يحتوي JSON المعاد على:

  • العدد الإجمالي للطلاب
  • متوسط العمر
  • عدد الطلاب حسب البرنامج

إضافة 3 — الترقيم​

عدل نقطة النهاية GET /api/students لدعم الترقيم:

GET /api/students?page=0&size=10&sort=lastName

إضافة 4 — إدارة الأخطاء المركزية​

أنشئ مدير استثناءات عالمي يقوم بـ:

  • إعادة رسائل خطأ واضحة في JSON
  • معالجة الحالات: طالب غير موجود (404)، بريد إلكتروني مكرر (409)، فشل التحقق (400)

تنسيق استجابة الخطأ المتوقع:

{
"status": 404,
"message": "طالب غير موجود بالمعرف: 99",
"timestamp": "2025-01-15T10:30:00"
}

إضافة 5 — الانتقال إلى PostgreSQL​

استبدل H2 بـ PostgreSQL:

  • أنشئ قاعدة بيانات studentdb في PostgreSQL
  • عدل التكوين للإشارة إلى PostgreSQL
  • تحقق من أن البيانات تستمر بعد إعادة تشغيل التطبيق

التسليمات​

#التسليمالتنسيق
1الكود المصدري الكامل للمشروعمستودع Git أو ZIP
2لقطات شاشة Postman للاختبارات العشرة (7 + 3 أخطاء)صور
3لقطة شاشة لوحدة التحكم H2 مع البياناتصورة
4إكمال ما لا يقل عن 2 من التمارين الإضافيةكود
5إجابات على أسئلة المراجعة (أدناه)مستند نصي

أسئلة المراجعة​

أجب عن هذه الأسئلة بكلماتك الخاصة:

  1. ما هي مسؤولية كل طبقة (Controller، Service، Repository)؟
  2. لماذا نقسم الكود إلى طبقات منفصلة؟
  3. ما الفرق بين @RestController و@Service؟
  4. كيف يقوم Spring Data JPA بتوليد استعلامات SQL تلقائيًا؟
  5. ما هو كود HTTP الذي يجب إرجاعه بعد إنشاء ناجح؟ بعد حذف؟
  6. لماذا نتحقق من فريدة البريد الإلكتروني في الخدمة وليس فقط في قاعدة البيانات؟
  7. ماذا يحدث إذا أرسلنا JSON غير صالح إلى Controller؟
  8. ما الفرق بين findById() الذي يعيد Optional وطريقة تعيد الكائن مباشرة؟

معايير التقييم​

المعيارالنقاط
تنفيذ العمارة الطبقية بشكل صحيح (Controller → Service → Repository)20%
كيان Student مع جميع التحقق15%
Repository مع طرق مخصصة10%
خدمة مع منطق تجاري كامل (تحقق، استثناءات)20%
Controller مع 5 نقاط نهاية CRUD وظيفية20%
اختبارات Postman ناجحة (حالات عادية + حالات خطأ)10%
تمارين إضافية5%
المجموع100%

نصيحة

إذا كنت عالقًا، لا تبقَ أكثر من 15 دقيقة على مشكلة. استشر TP3.1 لترى كيف تم ذلك، ثم عد هنا وحاول إعادة التنفيذ دون النظر.


⬅️ TP3.1: عمارة CRUD (موجه) | ⬅️ العودة إلى الوحدة 3