REST API - עקרונות, חוזים, ודפוסי פרודקשן
REST הוא סגנון ארכיטקטוני לתקשורת בין מערכות על גבי HTTP. כדי שזה יעבוד בפרודקשן נדרש יותר מ-GET ו-POST.
1) HTTP כשפה של המערכת
HTTP מגדיר סט פעולות (Methods), סטטוסים (Status Codes), כותרות (Headers) וגוף (Body). השרת מציע "משאבים" (Resources) והלקוח מבצע עליהם פעולות.
Methods
- GET - קריאה
- POST - יצירה
- PUT - החלפה מלאה
- PATCH - עדכון חלקי
- DELETE - מחיקה
Status Codes
- 200, 201 - הצלחה
- 400 - בקשה לא תקינה
- 401/403 - אימות/הרשאה
- 404 - לא נמצא
- 409 - קונפליקט
- 429 - יותר מדי בקשות
- 500 - שגיאת שרת
JSON
פורמט נתונים נפוץ להעברת אובייקטים. בפועל חשוב לאכוף סכמות, לא רק "לזרוק dict".
ב-FastAPI משתמשים ב-Pydantic כדי לבצע ולידציה.
2) עקרונות REST שאנשים מפספסים
Idempotency: פעולה שאפשר לבצע שוב ושוב בלי לשנות את התוצאה אחרי הפעם הראשונה. GET ו-PUT אמורים להיות idempotent, POST בדרך כלל לא.
מה המשמעות המעשית?
אם לקוח שולח בקשה פעמיים בגלל רשת לא יציבה, מערכת טובה יודעת לא לשבור נתונים. לכן:
- ביצירת משאב קריטי - שוקלים idempotency key.
- בעדכון - משתמשים ב-ETag/If-Match או version field למניעת lost updates.
- בטעויות זמניות - מגדירים retries בצד לקוח עם backoff, אבל בזהירות כדי לא ליצור עומס.
3) תבנית שגיאות אחידה
הטעות הנפוצה היא להחזיר הודעת טקסט שונה בכל נקודת קצה. במקום זה מגדירים פורמט קבוע שכולל קוד פנימי, הודעה למפתח, ו-id לניטור.
{
"error": {
"code": "USER_NOT_FOUND",
"message": "No user with id=123",
"trace_id": "9f0b2d0c0a0b4c8e"
}
}
4) גרסאות API
מערכת אמיתית משתנה. כדי לא לשבור לקוחות קיימים משתמשים בגרסאות. הדרך הפשוטה: prefix בנתיב.
GET /api/v1/users/123
GET /api/v2/users/123
5) אבטחה בסיסית: Authentication ו-Authorization
אימות (Authentication) עונה על "מי אתה". הרשאות (Authorization) עונות על "מה מותר לך". ב-REST נהוג להשתמש ב-Bearer Token ב-Header.
Authorization: Bearer <access_token>
כללי זהב לאבטחה פרקטית
- לעולם לא מחזירים secrets ללקוח ולא שומרים אותם ב-localStorage אם אפשר להימנע.
- מגבילים קצב (rate limiting) - במיוחד endpoints שקשורים ל-LLM.
- מפרידים הרשאות לפי roles או scopes.
- מתעדים אירועים (audit logs) לפעולות רגישות.
6) דפוסי שימוש שכיחים
Pagination
רשימות גדולות מחייבות חלוקה לעמודים. דפוס פשוט: limit + cursor.
GET /api/v1/items?limit=50&cursor=eyJpZCI6MTAwfQ==
Cursor יציב יותר מ-page number כשנתונים משתנים.
Filtering + Sorting
מניחים שצד לקוח רוצה סינון, ולכן מאפשרים query params סטנדרטיים.
GET /api/v1/orders?status=paid&sort=-created_at
סימן מינוס מציין מיון יורד.
כדי לראות איך כל זה מתרגם לקוד אמיתי, ממשיכים לדוגמת CRUD ב-FastAPI.
לקריאת הפרק FastAPI CRUD