מערך שיעור: CRUD מלא — Server + Database
משך: יום לימוד מלא — 6 שעות אקדמיות (270 דקות).
מטרת השיעור: לחבר את כל השבוע (ובעצם את כל הקורס עד כה) למערכת אחת: API שמקבל בקשות HTTP, מבצע CRUD על מסד נתונים, ומחזיר תשובות נכונות. ולבדוק אותה כמו שצריך.
בסוף השיעור הסטודנטים צריכים:
- להסביר את החלוקה main.py / db.py, ולמפות כל Endpoint לפעולת SQL ולקודי ההצלחה והכישלון שלו.
- לממש Students API מלא (POST, GET הכול, GET לפי id, PUT, DELETE) מעל
db.py, עם ולידציה, 201/204/400/404/409/422. - לבדוק את המערכת ב-Swagger UI ועם תסריט בדיקה, לפי Test Plan שמכסה את כל מקרי הקצה.
דגש קריטי: “שמור את הארכיטקטורה פשוטה מאוד” (מהדרישות). שני קבצים, בלי ORM, בלי Design Patterns, בלי Dependencies של FastAPI ובלי async. אם סטודנטים מתקדמים מציעים Repository Pattern או SQLAlchemy, להגיד “מעולה, בהמשך המסלול” ולהישאר בפשוט.
מהלך השיעור
| חלק בשיעור | משך | הערות ודגשים |
|---|---|---|
| הארכיטקטורה + טבלת המיפוי | 35 דק' | לצייר את שתי השכבות על הלוח. להוסיף לטבלת החוזה של אתמול עמודת “Status Code”. בקשה אחת מקצה לקצה. |
| הקמה + GET-ים | 35 דק' | כולם מקימים students-api, מעתיקים את db.py מאתמול, ו-seed. הוכחת התמדה: הפעלה מחדש. |
| הפסקה | 15 דק' | |
| POST, PUT, DELETE | 50 דק' | לבנות יחד. שלוש שכבות הבדיקה (422/400/409). טבלת 14 הבקשות ב-Swagger. |
| בדיקות: Swagger, curl, תסריט | 35 דק' | smoke_test.py. לשבור בכוונה (204→200) ולראות FAIL. |
| הפסקה | 15 דק' | |
| Mini Project: Products API | 70 דק' | עבודה עצמאית. המרצה עובר ובודק הפרדת שכבות וקודי סטטוס. |
| בדוק את עצמך + סיכום השבוע | 15 דק' |
דגשים להעברת השיעור
- הרגע של “הכול מתחבר”: להצביע בקול על כל שבוע תוך כדי בנייה: Port ו-HTTP (נושא מחשב, מערכת הפעלה ורשת), dict, JSON ו-Exceptions (נושא Python), Classes ו-Pydantic (נושא OOP), SQL (נושא Backend ומסדי נתונים).
- Route = 3 שלבים (קלט → קריאה אחת ל-db → תרגום). לבדוק כל Route שסטודנטים כותבים מול הכלל הזה.
- שלוש שכבות בדיקה (422/400/409) — לצייר כטבלה, ולשאול לכל שגיאה “מי החזיר אותה?”.
- 204 בלי גוף — טעות נפוצה. להראות.
- תסריט הבדיקה הוא הכלי החשוב ביותר לשבוע הבא (פרויקט האינטגרציה וה-Debugging). לוודא שכולם יודעים להריץ אותו.
- מסד ריק לבדיקות — להראות את הכישלון כשמריצים פעמיים בלי לנקות.
- בדיקה שגויה היא גם באג. אם הבדיקה מצפה ל-409 אבל הנתונים שלה מפרים כלל אחר (שם של תו אחד → 400), היא תיכשל, והבאג בבדיקה. שווה להדגים: גם קוד בדיקות צריך לבדוק.
מושגים
| מושג | הסבר קצר |
|---|---|
| Layered Architecture | שכבות: API (main.py) / Data (db.py) / Database. |
| Route | קלט → קריאה ל-db → תרגום ל-HTTP. |
| Mapping Table | Endpoint ↔ פונקציה ↔ SQL ↔ קודים. |
| Seed Data | נתוני התחלה (seed.py). |
| Persistence | הנתונים שורדים הפעלה מחדש. |
Input Model (...In) | מודל Pydantic של מה שה-Client שולח. |
| Business Validation | כללים שלנו → 400. |
| 201 / 204 | נוצר / הצלחה בלי גוף. |
| Swagger UI / OpenAPI | דף בדיקה ותיעוד אוטומטי / התיאור הסטנדרטי של ה-API. |
| End-to-End Test | בדיקה שמפעילה את המערכת מבחוץ, כמו Client. |
| Test Plan | רשימת בדיקות: מסלול שמח + כל מקרי הכישלון. |
| Smoke Test | תסריט בדיקות מהיר ש"כל המערכת חיה". |
תרגיל חשיבה
שאלת פתיחה (תחילת היום): “יש לנו db.py מאתמול, שעובד ונבדק. יש לנו את FastAPI מנושא Backend ו-FastAPI. איפה לשים את ה-SQL: בתוך פונקציות ה-Route, או ב-db.py? תנו שתי סיבות.”
מהלך:
- דיון בזוגות. לאסוף טיעונים על הלוח.
- טיעונים צפויים: “פחות קבצים” (בעד SQL ב-Route), מול “סדר”, “שימוש חוזר” ו"בדיקות" (בעד db.py).
- לשאול שלוש שאלות מבחן:
- “מחר רוצים סקריפט seed שמכניס 100 סטודנטים. איפה הוא יקבל את ה-INSERT?” → מ-
db.py. - “עוברים ל-PostgreSQL. כמה קבצים משתנים?” → רק
db.py. - “יש באג ב-SQL. איך בודקים אותו בלי להריץ שרת?” →
check_crud.py.
- “מחר רוצים סקריפט seed שמכניס 100 סטודנטים. איפה הוא יקבל את ה-INSERT?” → מ-
- מסכמים: הפרדה = שימוש חוזר + החלפה קלה + בדיקה נפרדת.
מה המרצה מראה בסוף: את הציור של שלוש השכבות, ושלושה “Clients” שונים שמשתמשים באותו db.py: main.py (שרת), seed.py ו-check_crud.py. משפט סיום: “אם קוד יכול לשמש רק את המקום שבו הוא נכתב, הוא כתוב במקום הלא נכון. ובשבוע הבא תבנו בדיוק כך פרויקט אינטגרציה שלם.”