כיצד להגדיר מטמון HTTP ל-API: ETag, Last-Modified, Vary

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

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
כיצד להגדיר מטמון HTTP ל-API: ETag, Last-Modified, Vary
בינוני
מ- 1 יום עד 3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

מטמון HTTP ב-API: היכן זה נשבר ומה הלקוח מפסיד

מטמון HTTP הוא שכבה שנמצאת בין הלקוח ל-backend ומחליטה אם אפשר להחזיר תשובה מוכנה מבלי להעיר את האפליקציה. כשהוא לא קיים, כל בקשה של לקוח נייד, כל רינדור מחדש של הממשק וכל קריאה חוזרת מהאינטגרציה מגיעים למסד הנתונים ומחשבים מחדש את אותה תוצאה.

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

מכאן נכנס לתוקף אפקט הדומינו. העומס על ה-backend גדל יחד עם מספר הלקוחות, ולא יחד עם נפח הנתונים החדשים בפועל — תמונה אופיינית שבה 80% מהתעבורה מגיעה לאותם מדריכים, קטלוגים ורשימות.

בעומס שיא, יתרת המשאבים נגמרת לפני שמגיע התעבורה העיקרית, ומתחילות תקלות בשיאים: תחילה פסקי זמן בודדים, אחר כך שגיאות המוניות בנקודות הקצה ה"חמות" ביותר, דווקא אלו שנקראות בתדירות הגבוהה ביותר.

מטמון API מסיר את העומס הזה ברמת הפרוטוקול, ולא באמצעות הוספת שרתים.

כותרות ETag ו-Last-Modified מאפשרות ללקוח לשאול "האם השתנה" ולקבל תשובה קצרה במקום גוף מלא, Vary מפריד את המטמון לפי מאפייני הבקשה הנדרשים, והנחיות רעננות נכונות קובעות כמה זמן התשובה חיה מבלי לפנות לאפליקציה. כתוצאה מכך, בקשות חוזרות נסגרות בגבול, וה-backend עוסק רק בנתונים חדשים.

מפרקים היכן בדיוק נשבר מטמון HTTP ב-API אמיתיים ואיך להגדיר אותו כך שהשהיות ותקלות יפסיקו להיות צוואר בקבוק.

מה נותן קэширование מנוהל: אפקטים מדידים

קэширование HTTP מפסיק להיות "הגדרה על העין" כאשר לכל תגובה יש ולידטור: ETag או Last-Modified.

הלקוח שולח If-None-Match / If-Modified-Since, השרת מגיב ב-304 Not Modified ללא גוף — זמן התגובה של ה-API בבקשות חוזרות יורד פי כמה, מכיוון שברשת עוברת רק הכותרת, ולא המטען השימושי.

הבקנד לא בונה מחדש את התגובה: הפריקה מתרחשת לא על חשבון קэш בצד הלקוח, אלא על חשבון כך שהלוגיקה הכבדה כלל לא מופעלת.

הכותרת Vary פותרת את החצי השני של המשימה — הפרדה נכונה של הקэш לפי Accept-Encoding, Authorization ושפה. בלעדיה, פרוקסי מחזיר ללקוח אחד תגובה שנבנתה עבור אחר: הרשאות זרות, לוקאל שגוי, דחיסה שלא בפורמט הנכון.

זהו סוג נפרד של כשלים — לא נפילת שירות, אלא מסירה שקטה של נתונים שגויים, שמתגלים כבר בפרודקשן. קэширование מנוהל מסיר אותו ברמת החוזה, ולא בטלאים בקוד.

יציבות תחת עומס — היא התוצאה. כאשר חלק הבקשות החוזרות שנסגרות על ידי ולידציה גדל, עומס השיא על הבקנד מפסיק להתאים את עצמו למספר הלקוחות: אותם שרתים מחזיקים יותר תעבורה, וזמן התגובה נשאר צפוי. מפרקים כיצד זה מוגדר בפועל — מבחירת הוולידטור ועד למדיניות עבור פרוקסי ו-CDN.

גישות לקאשינג: השוואת מצבים ומגבלות

קאשינג הוא לא "להפעיל ולשכוח", אלא בחירה של מצב בהתאם לפרופיל התעבורה. להלן — חלופות אמיתיות, שביניהן יש לבחור בעת תכנון API, עם התאמתן ומגבלותיהן. בנפרד יש לבחון מי מנהל את המדיניות: האפליקציה, ה-reverse proxy או הלקוח.

אפשרות מתי מתאימה מגבלות
ללא קאשינג נתונים אישיים, פעולות תשלום, תגובות התלויות בהרשאות המשתמש כל בקשה מגיעה למקור, העומס והשהיה גדלים
Cache-Control: no-store תגובות רגישות שאסור להשאיר על הדיסק לא מספק שיפור במהירות, רק מגן על הנתונים
max-age + public ספריות ציבוריות, קטלוגים, תוכן שמשתנה לעתים רחוקות התיישנות נתונים בטווח ה-TTL, נדרש איפוס בעת עדכון
ETag + If-None-Match משאבים שמשתנים לעתים לא תכופות, אך חייבים להיות עדכניים round-trip מיותר לבדיקה, תגובה 304 במקום גוף
Last-Modified + If-Modified-Since קבצים, סטטיקה, מסמכים עם תאריך שינוי דיוק עד לשנייה, הפעלות שווא בעת שמירה מחדש
Vary לפי כותרות תוכן שתלוי בשפה, בהרשאה, בסוג ההתקן מפצל את הקאש להרבה וריאנטים, נפח האחסון גדל
מדיניות מנוהלת ב-proxy כללים אחידים לעשרות שירותים דורשים תיאום עם האפליקציה, אחרת נוצר קונפליקט כותרות

לשלב מצבים יש כמעט תמיד: ETag לדינמיקה, max-age לסטטיקה, Vary במקום שבו התגובה תלויה בהקשר הבקשה. הסיכון המרכזי — אי-התאמה של כותרות בין האפליקציה ל-proxy: הלקוח מקבל תגובה מיושנת או, להיפך, הקאש לא עובד כלל.

בחירת הגישה נקבעת במדיניות מנוהלת ברמת ה-gateway, ולא בקוד של כל שירות. כך הכללים נשארים צפויים, ומגבלות הקאשינג נראות לפני השחרור, ולא אחרי התקלה.

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

מטמון API אינו "הפעלת תוסף", אלא רצף של החלטות: היכן נמצא המטמון, לפי איזה מפתח הוא מבחין בין תגובות, ובאיזה רגע הנתונים נחשבים מיושנים. להלן — כיצד אנו מבצעים עבודה כזו, כך שלאחר ההפעלה ההתנהגות תהיה צפויה, ולא "כאילו עובד".

  1. סקירת כותרות. אנו לוקחים תגובות API אמיתיות ובודקים מה השרת מחזיר כעת: האם קיימת Cache-Control עם max-age הגיוני, האם מוגדרת ETag או Last-Modified, והאם Vary על כותרות אימות ושפה אינו הולך לאיבוד. לעתים קרובות מתברר שחלק מהתגובות נשמרות במטמון במקום שבו אסור, וחלק — להיפך, אינן נשמרות במטמון כלל.
  2. תכנון מדיניות. עבור כל סוג משאב אנו מגדירים מצב: ספרי עזר ציבוריים — max-age ארוך עם stale-while-revalidate, נתונים אישיים — private ללא מטמון משותף, ישויות משתנות — אימות באמצעות ETag ותגובה 304. בנפרד אנו מתעדים את מפתח המטמון ואת מערך השדות ב-Vary.
  3. הגדרת מטמון. אנו רושמים כותרות ברמת האפליקציה וברמת שכבת הביניים, ומסנכרנים ביניהן כך שה-proxy לא ישכתב את מדיניות האפליקציה. אנו מגדירים עבודה תקינה עם בקשות מותנות If-None-Match ו-If-Modified-Since.
  4. בדיקת אי-תוקף. אנו מריצים תרחישים של שינוי נתונים: עדכון רשומה, שינוי הרשאות גישה, פרסום גרסה חדשה. אנו מוודאים שלאחר הכתיבה הלקוח ומטמון הביניים מקבלים נתונים עדכניים, ולא מחזירים נתונים מיושנים.
  5. בדיקת עומס. אנו בוחנים את שיעור התגובות 304 ואת הפגיעות במטמון, ואת זמן התגובה לפני ואחרי. המטרה — גידול בשיעור התגובות המאומתות והפחתת העומס על המקור.
  6. מסירת תיעוד. אנו מוסרים מפת מדיניות לפי נקודות קצה, כללי אי-תוקף והוראות למפתחים: אילו כותרות ניתן לשנות, ואילו ישברו את המטמון.
  7. תמיכה שוטפת. לאחר ההפעלה אנו עוקבים אחר מדדי הפגיעות ומתקנים את max-age במקומות שבהם הנתונים משתנים בתדירות גבוהה מהצפוי.

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

מה הלקוח מקבל לידיו: קונפיגורציות ותקנות

העבודה עם HTTP-קשירה אינה מסתיימת ב"הפעלנו כותרות ושכחנו", אלא בסט של ארטיפקטים שנשארים במאגר הקוד וחיים זמן רב יותר מהקבלן. כל סעיף להלן הוא משהו שניתן לפתוח, לבדוק ולהעביר למהנדס חדש ללא הסברים בעל פה.

  • קונפיגורציות קשירה — קבצי עבודה עבור פרוקסי הפוך והיישום: כללים ל-Cache-Control (max-age, s-maxage, stale-while-revalidate), יצירת ETag ו-Last-Modified, הגדרת Vary עבור Accept-Encoding והרשאה. עם הערות מדוע נבחר דווקא סט דירקטיבות זה עבור כל סוג תגובה.
  • תרשימי זרימה — דיאגרמות של נתיב הבקשה: לקוח → CDN → פרוקסי הפוך → יישום → אחסון. בתרשים מסומן באיזה שכבה נשמרת התגובה בקשירה, היכן מתרחשת ריוולידציה ואיזו שכבה אחראית על invalidatsiya.
  • מדיניות invalidatsiya — תקנון איפוס: לפי תגיות משאבים, לפי קידומות URL, לפי אירוע שינוי נתונים. עם ציון מה מתנקה בכפייה ומה חי עד לפקיעת max-age, וכיצד זה מתייחס ללוגיקה העסקית.
  • תיעוד API — תיאור נקודות קצה עם ציון יכולת הקשירה: אילו תגובות פומביות, אילו פרטיות, היכן חובה הרשאה ומדוע תגובה כזו לא צריכה להיכנס לקשירה משותפת.
  • תקנונות בדיקה — רשימת תיוג לקבלה: בקרת כותרות תגובה, התנהגות ב-304 Not Modified, תקינות Vary תחת Accept-Encoding שונים, היעדר דליפת נתונים פרטיים דרך קשירה משותפת.
  • ניטור והתראות — מדדי שיעור פגיעות בקשירה, זמן תגובה בפספוס וריוולידציה. ספים שבלעדיהם מהנדס מקבל התראה ולא לומד על הבעיה מהמשתמשים.
  • הוראות rollback — סדר פעולות אם מדיניות קשירה חדשה שוברת את הפלט: כיצד לאפס במהירות את הקשירה בכל השכבות ולהחזיר את הקונפיגורציה הקודמת.

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

מקרה בוחן: כיצד מטמון מנוהל הסיר פרצי כשלים

הפרויקט — מרקטפלייס עם קטלוג של כמה מאות אלפי פריטים ואפליקציית מובייל שפנתה ל-API בכל מסך. הקצה האחורי לא החזיר כותרות מטמון: Cache-Control לא הוגדר, ETag לא חושב, והתגובות נשלחו עם no-store כברירת מחדל. כל הפעלה של האפליקציה וכל מעבר בקטלוג פגעו ישירות במסד הנתונים.

מה היה לפני ההטמעה

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

מה שינו

הגדרנו מטמון מנוהל ברמת שער ה-API והאפליקציה. עבור ספרי עזר וכרטיסי מוצר הפעלנו ETag ו-Last-Modified — בקשה חוזרת ללא שינויים מחזירה 304 Not Modified ואינה מגיעה לקצה האחורי.

עבור רשימות התלויות במסננים, בתפקידים ובשפה, הגדרנו Vary לפי הכותרות הנדרשות, כדי לא להחזיר גרסה שגויה של התגובה. נתונים ציבוריים קיבלו Cache-Control עם הנחיות נפרדות של max-age ו-stale-while-revalidate: הלקוח מקבל עותק מיושן בזמן שברקע נמשכת גרסה עדכנית. את האינוולידציה קשרנו לאירועי שינוי מוצר, ולא לטיימר.

מה נהיה

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

פרקטיקת ההטמעה הראתה את העיקר: הרווח אינו מגיע מהכותרת עצמה, אלא ממדיניות עקבית — מה נשמר במטמון, לכמה זמן, לפי אילו מאפיינים הוא נבדל ומתי הוא מתאפס. גישה זו אנו מיישמים גם בפרויקטים אחרים על FastAPI וסטאקים דומים, שבהם חשובה צפיות תחת עומס.

במה שונה ETag מ-Last-Modified ומתי צריך Vary?

ETag ו-Last-Modified פותרים משימה אחת — לתת ללקוח דרך זולה לבדוק אם המשאב השתנה, בלי להעביר את גוף התגובה במלואו. Last-Modified נשען על זמן העריכה האחרונה ופועל ברזולוציה של שנייה: אם שני שינויים נכנסו באותה שנייה או שהקובץ נכתב מחדש עם אותו תוכן, התג משקר.

ETag הוא טביעת אצבע של גרסה מסוימת של הייצוג, ולכן הוא תופס שינויים שהזמן לא רואה, ופועל כראוי בהגשה מ-CDN ובהרכבת תגובה ממספר מקורות.

בפועל לא מעמידים אותם זה מול זה, אלא שמים אותם יחד: ETag נותן בדיקה מדויקת, Last-Modified נשאר מאמת גיבוי למתווכים שלא יודעים לעבוד עם טביעת אצבע.

הלקוח שולח בקשה מותנית עם If-None-Match ו-If-Modified-Since, השרת משווה ומחזיר או את הגוף, או תגובה קצרה «לא השתנה» — חיסכון בתעבורה ובזמן התגובה בסדר גודל, לא באחוזים.

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

Vary עונה על שאלה אחרת — לא «האם זו אותה גרסה», אלא «האם זה אותו לקוח». אם התגובה תלויה בכותרת Accept, Accept-Encoding, Accept-Language או באימות, בלי Vary מטמון מתווך יגיש גרסה של מישהו אחר: תגובה דחוסה — ללקוח בלי תמיכה בדחיסה, אנגלית — למי שביקש רוסית.

Vary: Accept-Encoding ו-Vary: Accept-Language סוגרים את זה, אבל כל כותרת שנוספת מפצלת את המטמון למספר גדול יותר של וריאנטים, ולכן צריך למנות רק את מה שבאמת משפיע על גוף התגובה.

בנפרד ראוי לציין Vary: Authorization ותגובות פרטיות: או שמסמנים אותן ב-Cache-Control: private, או שאוסרים מטמון altogether, אחרת נתונים אישיים ישקעו במטמון משותף.

נוח לבדוק את הצירוף לפי היומן: שיעור התגובות «לא השתנה» לבקשות מותנות מראה אם האימות עובד, ושיעור הפגיעות במטמון לפי כל וריאנט Vary — אם האחסון לא מתנפח.

ספקות טכניים נפוצים בעת הגדרת מטמון

המטמון לרוב כבר פרוס — ב-CDN, ב-reverse-proxy או באפליקציה עצמה, והשאלה אינה "האם להפעיל", אלא "איך לא לשבור את מה שעובד". מתחילים בספירת מלאי: אילו נתיבים נשמרים במטמון, לפי אילו מפתחות, מי מגדיר את הכותרות — ה-proxy או ה-backend. לאחר מכן משנים באופן ממוקד: תחילה תגובות ללא התאמה אישית, אחר כך כל השאר, עם בדיקה בכל שלב.

אימות ומטמון מתנגשים במקום שבו התגובה תלויה במשתמש, אך מפתח המטמון תלוי רק ב-URL. הפתרון — או Cache-Control: private מפורש עבור נתיבים כאלה, או Vary: Authorization, או הפרדה למעגל ציבורי ומעגל פרטי.

אנחנו לא מסתמכים על "כברירת מחדל זה לא יישמר במטמון": בודקים כל נתיב שבו בתגובה יש נתוני משתמש.

בדיקת אי-תוקף היא שלב נפרד, ולא פורמליות. בודקים מה קורה בעת עדכון משאב: האם משתנה ETag, האם מגיע 304 לבקשה מותנית, האם התגובה הישנה יוצאת מה-proxy לאחר PURGE. אם אי-התוקף אינו פועל, הלקוח מקבל נתונים מיושנים ולא מבין מדוע.

המטמון כבר פרוס אצלנו — האם נצטרך לבנות הכל מחדש?

לא. תחילה מתעדים את ההתנהגות הנוכחית: אילו כותרות מחזיר ה-backend, מה ה-proxy דורס, היכן המפתחות חלוקים. בנייה מחדש נדרשת רק במקום שבו הכללים מתנגשים — בדרך כלל מדובר ב-2-3 נתיבים מתוך עשרות.

איך לא לשבור את האימות בעת הפעלת המטמון?

מפרידים בין המעגלים: תגובות ציבוריות נשמרות במטמון לפי URL, תגובות פרטיות מסומנות כ-private או מקבלות Vary: Authorization. לאחר ההפעלה מריצים תרחישים עם תפקידים שונים ובודקים שהמשתמש אינו מקבל תגובה של מישהו אחר.

איך לוודא שאי-התוקף עובד?

בודקים את השרשרת: עדכנו משאב — האם השתנה ETag או Last-Modified, האם השרת החזיר 304 לבקשה מותנית, האם התגובה הישנה יצאה מה-proxy. אם לפחות שלב אחד אינו פועל, המטמון מחזיר נתונים מיושנים.

ספקות אלה עולים כמעט בכל פרויקט — וכמעט תמיד נפתרים בהגדרה ממוקדת, ולא בשכתוב. תארו את התצורה שלכם — נחזור עם הערכה ותוכנית בדיקה.

נדון במשימה שלך בנושא מטמון API

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

מה שמועיל לצרף לתיאור:

  • כותרות התגובה הנוכחיות של ה-API — Cache-Control, ETag, Last-Modified, Vary: רואים מה כבר נשלח ללקוחות ואיפה הלוגיקה מתפרקת;
  • ארכיטקטורה: מונוליט או מספר שירותים, האם יש CDN או פרוקסי הפוך לפני האפליקציה;
  • אילו מתודות ונקודות קצה נשמרות במטמון, ואילו חייבות להישאר טריות לחלוטין (תשלומים, יתרות, סטטוסים של הזמנות);
  • כיצד בנויה ההרשאה — טוקנים בכותרת, cookie, סשנים: מזה תלוי הכיול הנכון של Vary ופרטיות המטמון;
  • תלונות מהמשתמשים או מדדים: נתונים מיושנים, בקשות מיותרות, עלייה בעומס על בסיס הנתונים;
  • מגבלות: תקנות, דרישות אבטחה, לוחות זמנים שאסור להזיז.

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

אם במהלך הניתוח יצוצו הסתעפויות — נדון בהן עם המהנדס שלך, כדי שהפתרון ישתלב בתשתית הקיימת ולא ידרוש בנייה מחדש שלה.

תאר את המשימה — נחזור עם הערכה ותוכנית.