# מערך שיעור: Controllers📋 מערך מרצה

משך: 2.75 שעות אקדמיות (125 דקות).

מטרת השיעור: הסטודנטים יבנו Controller מלא עם CRUD, וישלטו ב-IActionResult לשליטה על תגובות.

בסוף השיעור הסטודנטים צריכים: לכתוב Controller עם [Route]/[HttpGet]/[HttpPost] נכונים, להחזיר IActionResult מתאים לכל תרחיש, ולהסביר [FromBody].

דגש קריטי: זהו שיעור-הליבה של API אמיתי — הקדישו זמן מספק לתרגול מודרך, לא רק הדגמה.

---

## מהלך השיעור

| חלק בשיעור | משך | הערות ודגשים |
| --- | --- | --- |
| פתיחה וחיבור | 5 דקות | הראו Program.cs עם endpoints של כמה משאבים מעורבבים — "מה קורה עם 50 כאלה?" |
| החיבור בין הקבצים | 12 דקות | מבנה תיקיות (`Program.cs` / `Models/` / `Controllers/`); `AddControllers()` + `MapControllers()` ב-`Program.cs`; "מי קורא ל-Controller" — סריקה בהפעלה → טבלת routing → הפעלת Action. הדגישו: זו אותה זרימה של `app.MapGet`, רק מגולה מה-attributes |
| שלב 1: שלד Controller ריק | 10 דקות | `[ApiController]`, `[Route("api/[controller]")]`, `ControllerBase` — בלי Actions עדיין; הקובץ החדש `Controllers/StudentsController.cs` |
| שלב 2: Action ראשון — GetAll | 15 דקות | `[HttpGet]`, `Ok()` — קשרו ל-200 מיחידת ה-HTTP |
| שלב 3: Action שני — GetById | 15 דקות | `[HttpGet("{id}")]`, `NotFound()` — Route Parameter בהקשר Controller |
| שלב 4: Action שלישי — Create | 20 דקות | `[HttpPost]`, `[FromBody]`, `CreatedAtAction` — חיבור ל-JSON ול-201/Location |
| שלב 5: Action רביעי — Delete | 15 דקות | `[HttpDelete("{id}")]`, `NoContent()` |
| תרגול מודרך | 33 דקות | תרגיל 1+2 + התחלת פרויקט מסכם |

---

## דגשים להעברת השיעור

- הקדישו זמן אמיתי לחלק "החיבור בין הקבצים" לפני קוד ה-Controller — הטעות הנפוצה של הסטודנטים היא לחשוב שה-Controller "רץ" כמו תוכנית. הבהירו: הוא ארגז פונקציות שה-Framework מגלה בהפעלה ומפעיל בתגובה לבקשה. הראו בפועל מה קורה כשמוחקים את `MapControllers()` — כל בקשה חוזרת `404` למרות שהקוד מתקמפל.
- זהו שיעור שדורש הרבה תרגול מעשי בפועל (Postman/curl/Swagger) — לא להסתפק בקוד על שקופית, הריצו endpoints אמיתיים מול Postman/דפדפן.
- הראו את ה-URL שנוצר אוטומטית מ-`[controller]` בפועל — סטודנטים צריכים לראות בעיניים ש-`StudentsController` → `api/students`.
- קשרו CreatedAtAction בבירור ל-Status Code `201` + `Location` header מיחידת ה-HTTP הקודמת — לא "עוד syntax", אלא יישום מדויק של המוסכמה שכבר נלמדה.

---

## מושגים

**Controller** — מחלקה שמאגדת endpoints קשורים, בקובץ נפרד תחת `Controllers/`.
**`AddControllers()` / `MapControllers()`** — שתי השורות ב-`Program.cs` שמפעילות את סריקת ה-Controllers ומחברות אותם ל-Pipeline; בלעדיהן — `404` על הכל.
**`[Route]`** — קובע URL בסיס.
**`[HttpGet]`/`[HttpPost]`/וכו'** — מתייגים Method לכל Action.
**`IActionResult`** — שולט על Status Code + Body יחד.

---

## תרגיל חשיבה

**שאלת פתיחה:** "אם `Program.cs` שלכם מכיל 50 `app.MapGet`/`MapPost` בודדים לניהול תלמידים, מוצרים והזמנות ביחד — מה קשה במציאת קוד ספציפי?"

**מהלך:** הובילו לתובנה: בלי ארגון, כל הלוגיקה יושבת "שטוחה" באותו קובץ בלי חלוקה הגיונית — בדיוק אותה בעיה כמו מחלקה עם אחריות מעורבבת (SRP) שכבר תרגלתם, רק ברמת ה-API כולו.

**מה המרצה מראה בסוף:** הראו את אותו API — פעם עם `app.MapGet` בודדים ב-`Program.cs`, ופעם עם `StudentsController`/`ProductsController` נפרדים — ההבדל בקריאות ובניווט בקוד ברור מיד. הריצו את שניהם בפועל ב-Postman והראו שההתנהגות זהה — ההבדל הוא רק ארגון, לא פונקציונליות.
