# Backend ו-HTTP: מי עושה מה, Methods ו-Status Codes<no value>

## מה בשיעור

השיעור הזה בנוי משני פרקים, באותו סדר כמו במצגת:

1. **פרק ראשון** — מהו Backend: Client, Server, Database, API ו-Endpoint
2. **פרק שני** — HTTP Methods ו-Status Codes

## פרק ראשון: מהו Backend — Client, Server, Database, API ו-Endpoint

### מה נלמד?

השבוע עוברים מתוכניות שרצות **אצלנו במחשב** לתוכנה ש**אחרים** מדברים איתה דרך הרשת. השיעור הזה נותן את התמונה הכללית ואת המילים:

- **Backend** ו-**Frontend**.
- **Client**, **Server** ו-**Database**: איך הם עובדים יחד.
- **API** ו-**Endpoint**.

### למה צריך את זה?

כל אפליקציה שאתם מכירים (וולט, אינסטגרם, אתר הבנק) בנויה משני חלקים: מה שרואים (Frontend), ומה שקורה "מאחורי הקלעים" (Backend): שמירת הנתונים, בדיקת ההרשאות, חישוב המחירים. מפתחי Full Stack כותבים את שניהם. מפתחי Data עובדים כל יום מול APIs ומסדי נתונים.

עד סוף השבוע תבנו Backend אמיתי: שרת שמקבל בקשות מהאינטרנט, שומר במסד נתונים, ומחזיר תשובות.

### הסבר מהבסיס

#### Frontend מול Backend

| | Frontend | Backend |
|---|---|---|
| מה זה | החלק ש**המשתמש רואה** ומפעיל | החלק שרץ **על השרת**, מאחורי הקלעים |
| איפה רץ | בדפדפן / באפליקציה בטלפון | על מחשב שרת (בענן / בחברה) |
| תפקיד | תצוגה, טפסים, כפתורים | לוגיקה עסקית, שמירת נתונים, אבטחה |
| דוגמה בחנות | דף המוצר, כפתור "הוסף לעגלה" | בדיקת מלאי, חישוב מחיר, שמירת ההזמנה |
| טכנולוגיות | HTML, CSS, JavaScript, React | **Python + FastAPI**, Node.js, Java... |

{{< box "analogy" "אנלוגיה: מסעדה" >}}
**Frontend** = אולם המסעדה: התפריט, השולחנות, המלצר שמקבל הזמנה. **Backend** = המטבח: שם באמת מכינים את האוכל, בודקים שיש מצרכים ושומרים על הכללים (לא מגישים בשר עם חלב בכשרה). **Database** = המחסן והמקרר: שם שמור כל המלאי. הסועד אף פעם לא נכנס למטבח או למחסן. הוא מדבר רק עם המלצר.
{{< /box >}}

#### Client, Server, Database — שלושת השחקנים

זוכרים את נושא מחשב, מערכת הפעלה ורשת? Client יוזם, Server עונה. עכשיו מוסיפים שחקן שלישי:

```text
  ┌──────────┐   HTTP Request    ┌──────────┐     SQL query     ┌──────────┐
  │  Client  │ ────────────────► │  Server  │ ─────────────────► │ Database │
  │ (browser,│                   │ (FastAPI │                    │ (MySQL)  │
  │  app)    │ ◄──────────────── │  backend)│ ◄───────────────── │          │
  └──────────┘   HTTP Response   └──────────┘     rows           └──────────┘
```

1. **Client** שולח **Request**: "תן לי את רשימת הסטודנטים".
2. **Server** (ה-Backend שלנו) מקבל, מבין מה מבוקש, בודק הרשאות וכללים.
3. השרת שואל את ה-**Database**: "SELECT כל הסטודנטים". (זה Client-Server **נוסף**: כלפי ה-Database, השרת שלנו הוא ה-Client! ראינו את זה בתרגול של נושא מחשב, מערכת הפעלה ורשת.)
4. ה-Database מחזיר שורות.
5. השרת מעבד ומחזיר **Response** ל-Client, בדרך כלל ב-**JSON** (נושא Python!).

**למה ה-Client לא מדבר ישירות עם ה-Database?** כי אז כל משתמש יכול היה לקרוא ולמחוק הכול. ה-Server הוא **השומר**: הוא מחליט מה מותר, בודק תקינות, ואוכף כללים. בדיוק כמו Encapsulation בנושא OOP, רק ברמת המערכת כולה.

#### API — Application Programming Interface

**API** = **ממשק** שתוכנה חושפת, כדי שתוכנות **אחרות** יוכלו להשתמש בה. ממשק = סט מוגדר של פעולות: מה אפשר לבקש, איך מבקשים, ומה מקבלים בחזרה.

כבר מכירים את הרעיון! ב-OOP, ה-**Public Interface** של Class (המתודות הציבוריות) הוא בדיוק "API של אובייקט". **Web API** הוא אותו רעיון דרך הרשת: במקום `shop.place_order(...)`, שולחים בקשת HTTP.

| OOP (נושא OOP) | Web API (השבוע) |
|---|---|
| `shop.get_product("P1")` | `GET /products/P1` |
| `shop.add_customer("Dana", ...)` | `POST /customers` עם Body |
| `ProductNotFoundError` | Status Code `404` |
| המתודות הציבוריות | ה-Endpoints |

#### Endpoint

**Endpoint** = **כתובת אחת ב-API + פעולה אחת**. השילוב של **Method** (GET/POST...) ו-**Path** (`/students`).

```text
GET     /students        → list all students
GET     /students/7      → get student 7
POST    /students        → create a new student
PUT     /students/7      → update student 7
DELETE  /students/7      → delete student 7
```

אלה **חמישה Endpoints** שונים, למרות שחלקם חולקים את אותו Path. ה-Method הוא חלק מה"כתובת".

**Resource** (משאב) = ה"דבר" שה-API מנהל: `students`, `products`, `orders`. מוסכמה מקובלת: Path ב**רבים**, ומזהה אחרי סלאש.

#### מה ה-Backend עושה בכל בקשה?

| שלב | דוגמה |
|---|---|
| **קבלה** — לפענח Method, Path, Body | `POST /students` עם `{"name": "Dana", ...}` |
| **ולידציה** — האם הנתונים תקינים? | גיל מספר, אימייל עם `@` |
| **לוגיקה** — הכללים העסקיים | אימייל לא קיים כבר |
| **גישה לנתונים** — Database | `INSERT INTO students ...` |
| **תשובה** — Status Code + JSON | `201 Created` + הסטודנט החדש |

### איך נראית תשובה של API

כשה-Client פונה ל-API, הוא שולח **בקשה**, והשרת מחזיר **תשובה**. כך נראות שתיהן — למשל, בקשה ל-API של GitHub על משתמש בשם octocat:

```text
GET /users/octocat              <- the request
Host: api.github.com

HTTP/1.1 200 OK                 <- the response
Content-Type: application/json

{"login": "octocat", "name": "The Octocat", "public_repos": 8}
```

| חלק | מה הוא אומר |
|---|---|
| `GET /users/octocat` | ה-Method והנתיב — **מה** מבקשים |
| `200 OK` | קוד התשובה — הבקשה **הצליחה** |
| `Content-Type: application/json` | הגוף בפורמט **JSON** |
| `{"login": ...}` | הנתונים עצמם — לא עיצוב, לא דף, רק נתונים |

API מחזיר **נתונים** ולא תצוגה: כל Client — אתר, אפליקציה בטלפון או תוכנה אחרת — מקבל את אותם נתונים ומציג אותם בדרך שלו.

{{< box "analogy" "אנלוגיה: מסעדה" >}}
הסועד (**Client**) לא נכנס למטבח. הוא מזמין דרך המלצר, לפי התפריט — זה ה-**API**, וכל מנה בתפריט היא **Endpoint**. המטבח (**Server**) מכין את המנה, בעזרת מה שיש במזווה (**Database**), והמלצר מביא אותה בחזרה.
{{< /box >}}

בהמשך נלמד לבנות API כזה בעצמנו, עם **FastAPI**.

### טעות נפוצה

**הטעות 1: "ה-Frontend ישמור את הנתונים, למה צריך Backend?"** נתונים בדפדפן נשארים **אצל משתמש אחד**, במחשב אחד, וכל אחד יכול לשנות אותם. מחיר שנשמר בדפדפן? משתמש יכול לשנות אותו ל-1 ש"ח. **כל מה שצריך להיות אמין, משותף ומאובטח, חי ב-Backend.**

**הטעות 2: לבלבל בין API ל-Database.** ה-API הוא **הדלת**. ה-Database הוא **המחסן** מאחוריה. ה-Client לעולם לא מקבל גישה ישירה למחסן, ותמיד עובר דרך הדלת, עם הכללים שלה.

**הטעות 3: Paths שמתארים פעולות במקום משאבים.**

```text
GET  /getAllStudents
POST /createNewStudent
GET  /deleteStudent?id=7
```

המוסכמה (נקראת **REST**): ה-Path הוא **שם עצם** (המשאב), וה-**Method** הוא הפועל. `DELETE /students/7` ולא `GET /deleteStudent`. במיוחד: **GET לעולם לא משנה נתונים**. דפדפנים ורובוטים של מנועי חיפוש שולחים GET אוטומטית, ומחיקה דרך GET היא מתכון לאסון. (נרחיב בפרק השני.)

### סיכום

- **Frontend** = מה שהמשתמש רואה. **Backend** = לוגיקה, נתונים ואבטחה, על השרת.
- הזרימה: **Client → Server → Database → Server → Client**. השרת הוא השומר: ה-Client לא ניגש ישירות ל-Database.
- **API** = ממשק שתוכנה חושפת לתוכנות אחרות. ב-Web, דרך HTTP ו-JSON.
- **Endpoint** = Method + Path. `GET /students/7` ו-`DELETE /students/7` הם שני Endpoints שונים.
- מוסכמה: Path = **משאב** (שם עצם, ברבים). Method = **פעולה**. GET לא משנה נתונים.

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

### דוקומנטציה רשמית

- [MDN — Introduction to the server side](https://developer.mozilla.org/en-US/docs/Learn_web_development/Extensions/Server-side/First_steps/Introduction) — מה עושה Backend
- [MDN Glossary — API](https://developer.mozilla.org/en-US/docs/Glossary/API) — מה זה API
- [MDN Glossary — JSON](https://developer.mozilla.org/en-US/docs/Glossary/JSON) — הפורמט של התשובה

<!-- docs:end -->

## פרק שני: HTTP Methods ו-Status Codes

### מה נלמד?

- ארבעת ה-**HTTP Methods** המרכזיים: **GET**, **POST**, **PUT**, **DELETE**.
- איך הם ממופים ל-**CRUD**: Create, Read, Update, Delete.
- **Status Codes** בסיסיים: איזה קוד מחזירים מתי.
- איך נראות בקשה ותשובה בכל אחת מהפעולות.

### למה צריך את זה?

בנושא Students API – שרת עם מסד נתונים תכתבו שרת, ולכל Endpoint תצטרכו להחליט: איזה Method? איזה קוד להחזיר בהצלחה, ואיזה בכל סוג של כישלון? Client שמדבר עם השרת שלכם (אפליקציה, Frontend, שירות אחר) מחליט מה לעשות **לפי הקוד**: להציג את הנתונים, להראות "לא נמצא", או לבקש מהמשתמש לתקן טופס. קוד שגוי = Client שמתנהג לא נכון.

### הסבר מהבסיס

#### CRUD — ארבע הפעולות על נתונים

כמעט כל מערכת עושה ארבעה דברים עם הנתונים שלה:

| CRUD | משמעות | HTTP Method | SQL (ימים 3–4) |
|---|---|---|---|
| **C**reate | יצירה | **POST** | `INSERT` |
| **R**ead | קריאה | **GET** | `SELECT` |
| **U**pdate | עדכון | **PUT** | `UPDATE` |
| **D**elete | מחיקה | **DELETE** | `DELETE` |

**הטבלה הזו היא השבוע כולו.** כל שורה תהיה Endpoint, ופונקציה שמריצה SQL.

#### ארבעת ה-Methods

**GET — קריאה.**

- "תן לי": `GET /students`, `GET /students/7`.
- **אין Body.** כל המידע ב-Path וב-Query (בשיעור הבא).
- **לא משנה שום דבר** בשרת. נקרא **Safe** (בטוח). אפשר לשלוח אותו 100 פעמים, ושום דבר לא ישתנה.

**POST — יצירה.**

- "צור משהו חדש": `POST /students`, עם **Body** שמתאר אותו.
- כל שליחה יוצרת **עוד** פריט. שתי שליחות = שני סטודנטים.
- בדרך כלל השרת קובע את המזהה (`id`) ומחזיר את הפריט החדש.

**PUT — עדכון (החלפה).**

- "עדכן את הפריט הזה": `PUT /students/7`, עם **Body** של **כל** הנתונים החדשים.
- שליחה חוזרת של אותה בקשה = אותה תוצאה (הסטודנט נשאר עם אותם ערכים). נקרא **Idempotent**.

**DELETE — מחיקה.**

- "מחק את הפריט הזה": `DELETE /students/7`.
- **אין Body** בדרך כלל.

(יש עוד Methods, כמו **PATCH** לעדכון חלקי של שדות בודדים, אבל ארבעת אלה מספיקים לשבוע.)

{{< box "analogy" "אנלוגיה: ספריית השאלה" >}}
**GET** = "אפשר לראות את הספר?" (מסתכלים, לא לוקחים). **POST** = "אני תורם ספר חדש לספרייה" (מתווסף עותק). **PUT** = "תחליפו את הכריכה הקרועה של ספר 7 בכריכה חדשה" (אותו ספר, מעודכן). **DELETE** = "תוציאו את ספר 7 מהמדפים".
{{< /box >}}

#### Status Codes — מה השרת עונה

נזכיר מנושא מחשב, מערכת הפעלה ורשת: **2xx** הצלחה, **4xx** טעות של ה-Client, **5xx** טעות של השרת. אלה הקודים שנשתמש בהם:

| קוד | שם | מתי מחזירים | דוגמה בשרת שלנו |
|---|---|---|---|
| **200** | OK | הצלחה, ויש תשובה | GET הצליח, PUT הצליח |
| **201** | Created | **נוצר** משאב חדש | POST הצליח |
| **204** | No Content | הצלחה, **בלי** Body | DELETE הצליח |
| **400** | Bad Request | הבקשה לא תקינה מבחינת כללים | גיל 7 (צריך 16+), שם ריק |
| **404** | Not Found | המשאב לא קיים | `GET /students/999` |
| **409** | Conflict | מתנגש עם מצב קיים | אימייל שכבר רשום |
| **422** | Unprocessable Content | **מבנה** הנתונים שגוי | חסר שדה, טקסט במקום מספר (FastAPI מחזיר אוטומטית) |
| **500** | Internal Server Error | **באג בשרת** | Exception שלא נתפס בקוד שלנו |

**עקרון ההחלטה:**

```text
Did it work?
├── yes → created something new?  → 201
│         nothing to return?      → 204
│         otherwise               → 200
└── no  → the client's fault?
          ├── resource doesn't exist        → 404
          ├── wrong structure / types       → 422
          ├── breaks a business rule        → 400
          ├── conflicts with existing data  → 409
          └── our code crashed              → 500  (fix the bug!)
```

#### 4xx מול 5xx — למה זה חשוב?

- **4xx** = "**אתה** (ה-Client) צריך לשנות משהו": לתקן את הטופס, או לבקש משהו שקיים. ניסיון חוזר **בלי שינוי** ייכשל שוב.
- **5xx** = "**אני** (השרת) נכשלתי". ה-Client לא עשה כלום רע. צריך לתקן את קוד השרת.

**שרת שמחזיר 500 על קלט רע של משתמש מכיל באג**: הוא היה צריך לבדוק את הקלט ולהחזיר 4xx. (זוכרים את שרת המחשבון מנושא מחשב, מערכת הפעלה ורשת, שקרס על "hello"?)

### בקשות ותשובות — דוגמאות

כך נראות הבקשות לכל אחת מהפעולות, והקוד שהשרת מחזיר:

```text
POST   /students     {"name": "Dana"}   -> 201 Created
GET    /students/7                      -> 200 OK
PUT    /students/7   {"name": "Dana C"} -> 200 OK
DELETE /students/7                      -> 204 No Content
GET    /students/99                     -> 404 Not Found
```

### מתי שולחים Body

| Method | Body? | מה יש בו |
|---|---|---|
| `GET` | לא | רק קוראים — אין מה לשלוח |
| `POST` | **כן** | הנתונים של המשאב החדש, ב-JSON |
| `PUT` | **כן** | כל הנתונים המעודכנים |
| `DELETE` | לא | מספיק המזהה שבנתיב |

בהמשך, ב-FastAPI, נראה איך השרת שלנו מקבל כל אחת מהבקשות האלה ומחזיר את הקוד הנכון.

### טעות נפוצה

**הטעות 1: GET שמשנה נתונים.**

```text
GET /students/7/delete
```

דפדפנים טוענים מראש קישורים, ומנועי חיפוש עוברים על כל קישור (Crawling). קישור כזה **ימחק סטודנטים בלי שאיש התכוון**. שינוי נתונים: רק POST, PUT ו-DELETE.

**הטעות 2: להחזיר 200 על כל דבר, עם "error" בתוך ה-JSON.**

```json
{"status": "error", "message": "student not found"}
```

...עם קוד 200. ה-Client (וגם דפדפנים ומערכות ניטור) רואים 200 ו"חושבים" שהכול הצליח. **הקוד הוא חלק מהתשובה.** סטודנט לא קיים = **404**.

**הטעות 3: 500 על קלט רע.** שרת שמריץ `int(age)` בלי לבדוק, וקורס על `"abc"` → 500. זו **לא** טעות של ה-Client שלא צריך להיענש. זה באג בשרת. בודקים קלט, ומחזירים **4xx** עם הסבר.

**הטעות 4: 404 מול 400.** `GET /students/999` (תקין, אבל לא קיים) ‏←‏ **404**. `POST /students` עם גיל `-5` (קיים, אבל לא חוקי) ‏←‏ **400**. השאלה: "האם המשאב לא קיים, או שהבקשה לא חוקית?"

### סיכום

- **CRUD ↔ HTTP**: Create = **POST**, Read = **GET**, Update = **PUT**, Delete = **DELETE**.
- **GET** בטוח: לא משנה נתונים, ואין לו Body. POST/PUT שולחים Body ב-JSON עם `Content-Type: application/json`.
- הצלחה: **200** (יש תשובה), **201** (נוצר), **204** (בלי תוכן).
- טעות Client: **404** (לא קיים), **400** (מפר כלל), **409** (התנגשות), **422** (מבנה או טיפוס שגויים).
- **500** = באג בשרת. קלט רע צריך לקבל 4xx, ולא לגרום לקריסה.
- הקוד הוא חלק מהתשובה. לא מחזירים 200 עם "error" בפנים.

<!-- docs:start — generated by scripts/intro6/site_docs.py; edit the links there -->

### דוקומנטציה רשמית

- [MDN — HTTP request methods](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods) — GET, POST, PUT, DELETE
- [MDN — HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status) — 200, 201, 404 ועוד
- [MDN — HTTP messages](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Messages) — מבנה של Request ו-Response

<!-- docs:end -->

<!-- exercises:start — generated by scripts/intro6/sync_site_exercises.py; edit scripts/intro6/exercises/ -->
## תרגול

שאלות הבנה על החומר של השיעור — בלי קוד.

### תרגיל 1: מי עושה מה?

לכל פעולה — האם היא קורית ב-Client, ב-Server או ב-Database?

1. המשתמש לוחץ על כפתור "הירשם".
2. בדיקה שהאימייל עוד לא רשום.
3. שמירת הסטודנט החדש לטווח ארוך.
4. הצגת ההודעה "נרשמת בהצלחה".
5. החלטה איזה Status Code להחזיר.

{{< solution >}}
1. **Client** — הממשק שהמשתמש רואה.
2. **Server** — הלוגיקה והכללים (בעזרת שאילתה למסד).
3. **Database** — שמירה קבועה.
4. **Client** — מציג את מה שהשרת החזיר.
5. **Server** — הוא שמחליט מה קרה ומחזיר תשובה.

```text
Client  --HTTP request-->  Server  --SQL query-->  Database
Client  <--HTTP response-- Server  <---rows------  Database
```
{{< /solution >}}

### תרגיל 2: Endpoints

כתבו את חמשת ה-Endpoints של API לניהול **מוצרים** (`/products`): רשימה, מוצר אחד, יצירה, עדכון ומחיקה. לכל אחד — Method, נתיב ומה הוא עושה.

{{< solution >}}
```text
GET     /products      -> list all products
GET     /products/7    -> get product 7
POST    /products      -> create a new product
PUT     /products/7    -> update product 7
DELETE  /products/7    -> delete product 7
```

**Endpoint** = Method + נתיב. אותו נתיב (`/products/7`) עושה שלושה דברים שונים לפי ה-Method.
{{< /solution >}}

### תרגיל 3: לקרוא תשובה של API

שרת החזיר את התשובה הבאה:

```text
HTTP/1.1 200 OK
Content-Type: application/json

{"login": "octocat", "name": "The Octocat", "public_repos": 8, "blog": null}
```

1. האם הבקשה הצליחה? איך יודעים?
2. באיזה פורמט הנתונים, ואיך יודעים?
3. מה השם של המשתמש, וכמה repositories יש לו?
4. מה המשמעות של `null`?

{{< solution >}}
1. **כן** — הקוד הוא **200 OK**.
2. **JSON** — כך כתוב ב-Header `Content-Type: application/json`, וכך גם נראה הגוף.
3. השם הוא **The Octocat**, ויש לו **8** repositories.
4. `null` ב-JSON פירושו **"אין ערך"** — למשתמש אין אתר (`blog`). (ב-Python, כשנקרא את זה בהמשך, זה יהפוך ל-`None`.)
{{< /solution >}}

### תרגיל 4: CRUD ↔ Methods

התאימו כל פעולת CRUD ל-HTTP Method, ולקוד התשובה המתאים כשהיא מצליחה.

```text
Create    Read    Update    Delete
```

{{< solution >}}
| CRUD | Method | קוד בהצלחה |
|---|---|---|
| Create | `POST` | **201** Created |
| Read | `GET` | **200** OK |
| Update | `PUT` | **200** OK |
| Delete | `DELETE` | **204** No Content |
{{< /solution >}}

### תרגיל 5: איזה קוד להחזיר?

לכל מקרה — איזה Status Code השרת צריך להחזיר?

1. נוצר סטודנט חדש.
2. ביקשו את סטודנט 99, והוא לא קיים.
3. ניסו ליצור סטודנט עם אימייל שכבר רשום.
4. נמחק סטודנט — ואין מה להחזיר.
5. שלחו גיל 7, אבל גיל מינימלי הוא 16.
6. השרת קרס בגלל באג בקוד.

{{< solution >}}
1. **201** — נוצר משהו חדש.
2. **404** — המשאב לא קיים.
3. **409** — התנגשות עם מה שכבר קיים.
4. **204** — הצליח, בלי גוף.
5. **400** — הבקשה לא עומדת בכללים (טעות של ה-Client).
6. **500** — טעות של ה-Server.
{{< /solution >}}

<!-- exercises:end -->
