Backend ו-HTTP: מי עושה מה, Methods ו-Status Codes

מטרות השיעור
  • להסביר מה תפקידו של ה-Backend ובמה הוא שונה מה-Frontend
  • לתאר את הזרימה Client → Server → Database → Server → Client
  • להגדיר API ו-Endpoint ולזהות אותם בכתובות אמיתיות
  • לקרוא בקשה ותשובה של API, ולהבין למה API מחזיר JSON
  • להסביר מה עושה כל אחת מ-GET, POST, PUT ו-DELETE, ולמפות אותן ל-CRUD
  • להבחין בין Method “בטוח” (לא משנה נתונים) לבין Method שמשנה
  • לבחור את ה-Status Code הנכון לכל תוצאה של בקשה
  • לקרוא בקשה ותשובה של HTTP, ולזהות את ה-Method ואת קוד התשובה

מה בשיעור

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

  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

FrontendBackend
מה זההחלק שהמשתמש רואה ומפעילהחלק שרץ על השרת, מאחורי הקלעים
איפה רץבדפדפן / באפליקציה בטלפוןעל מחשב שרת (בענן / בחברה)
תפקידתצוגה, טפסים, כפתוריםלוגיקה עסקית, שמירת נתונים, אבטחה
דוגמה בחנותדף המוצר, כפתור “הוסף לעגלה”בדיקת מלאי, חישוב מחיר, שמירת ההזמנה
טכנולוגיותHTML, CSS, JavaScript, ReactPython + FastAPI, Node.js, Java…
אנלוגיה: מסעדה

Frontend = אולם המסעדה: התפריט, השולחנות, המלצר שמקבל הזמנה. Backend = המטבח: שם באמת מכינים את האוכל, בודקים שיש מצרכים ושומרים על הכללים (לא מגישים בשר עם חלב בכשרה). Database = המחסן והמקרר: שם שמור כל המלאי. הסועד אף פעם לא נכנס למטבח או למחסן. הוא מדבר רק עם המלצר.

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

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

  ┌──────────┐   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
ProductNotFoundErrorStatus Code 404
המתודות הציבוריותה-Endpoints

Endpoint

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

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, BodyPOST /students עם {"name": "Dana", ...}
ולידציה — האם הנתונים תקינים?גיל מספר, אימייל עם @
לוגיקה — הכללים העסקייםאימייל לא קיים כבר
גישה לנתונים — DatabaseINSERT INTO students ...
תשובה — Status Code + JSON201 Created + הסטודנט החדש

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

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

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 — אתר, אפליקציה בטלפון או תוכנה אחרת — מקבל את אותם נתונים ומציג אותם בדרך שלו.

אנלוגיה: מסעדה

הסועד (Client) לא נכנס למטבח. הוא מזמין דרך המלצר, לפי התפריט — זה ה-API, וכל מנה בתפריט היא Endpoint. המטבח (Server) מכין את המנה, בעזרת מה שיש במזווה (Database), והמלצר מביא אותה בחזרה.

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

טעות נפוצה

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

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

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

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 לא משנה נתונים.

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

פרק שני: 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 MethodSQL (ימים 3–4)
CreateיצירהPOSTINSERT
ReadקריאהGETSELECT
UpdateעדכוןPUTUPDATE
DeleteמחיקהDELETEDELETE

הטבלה הזו היא השבוע כולו. כל שורה תהיה 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 לעדכון חלקי של שדות בודדים, אבל ארבעת אלה מספיקים לשבוע.)

אנלוגיה: ספריית השאלה

GET = “אפשר לראות את הספר?” (מסתכלים, לא לוקחים). POST = “אני תורם ספר חדש לספרייה” (מתווסף עותק). PUT = “תחליפו את הכריכה הקרועה של ספר 7 בכריכה חדשה” (אותו ספר, מעודכן). DELETE = “תוציאו את ספר 7 מהמדפים”.

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

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

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

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

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”?)

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

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

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

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

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

טעות נפוצה

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

GET /students/7/delete

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

הטעות 2: להחזיר 200 על כל דבר, עם “error” בתוך ה-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” בפנים.

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

תרגול

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

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

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

  1. המשתמש לוחץ על כפתור “הירשם”.
  2. בדיקה שהאימייל עוד לא רשום.
  3. שמירת הסטודנט החדש לטווח ארוך.
  4. הצגת ההודעה “נרשמת בהצלחה”.
  5. החלטה איזה Status Code להחזיר.
הצג פתרון
  1. Client — הממשק שהמשתמש רואה.
  2. Server — הלוגיקה והכללים (בעזרת שאילתה למסד).
  3. Database — שמירה קבועה.
  4. Client — מציג את מה שהשרת החזיר.
  5. Server — הוא שמחליט מה קרה ומחזיר תשובה.
Client  --HTTP request-->  Server  --SQL query-->  Database
Client  <--HTTP response-- Server  <---rows------  Database

תרגיל 2: Endpoints

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

הצג פתרון
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.

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

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

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?
הצג פתרון
  1. כן — הקוד הוא 200 OK.
  2. JSON — כך כתוב ב-Header Content-Type: application/json, וכך גם נראה הגוף.
  3. השם הוא The Octocat, ויש לו 8 repositories.
  4. null ב-JSON פירושו “אין ערך” — למשתמש אין אתר (blog). (ב-Python, כשנקרא את זה בהמשך, זה יהפוך ל-None.)

תרגיל 4: CRUD ↔ Methods

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

Create    Read    Update    Delete
הצג פתרון
CRUDMethodקוד בהצלחה
CreatePOST201 Created
ReadGET200 OK
UpdatePUT200 OK
DeleteDELETE204 No Content

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

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

  1. נוצר סטודנט חדש.
  2. ביקשו את סטודנט 99, והוא לא קיים.
  3. ניסו ליצור סטודנט עם אימייל שכבר רשום.
  4. נמחק סטודנט — ואין מה להחזיר.
  5. שלחו גיל 7, אבל גיל מינימלי הוא 16.
  6. השרת קרס בגלל באג בקוד.
הצג פתרון
  1. 201 — נוצר משהו חדש.
  2. 404 — המשאב לא קיים.
  3. 409 — התנגשות עם מה שכבר קיים.
  4. 204 — הצליח, בלי גוף.
  5. 400 — הבקשה לא עומדת בכללים (טעות של ה-Client).
  6. 500 — טעות של ה-Server.