בקשות אצווה

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

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

סקירה כללית

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

דוגמאות למצבים שבהם כדאי להשתמש בקיבוץ:

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

בכל מקרה, במקום לשלוח כל קריאה בנפרד, ניתן לקבץ את כל הקריאות לבקשת HTTP אחת. כל הבקשות הפנימיות חייבות להפנות לאותו API של Google.

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

הערה: התחביר של מערכת האצווה של ממשק ה-API של Gmail זהה לזה של מערכת עיבוד האצווה של OData, אבל הסמנטיקה שונה.

הערה: סביר להניח ש כמויות גדולות יותר של מודעות יגרמו להגבלת קצב של יצירת בקשות. לא מומלץ לשלוח קבוצות עם יותר מ-50 בקשות.

פרטי אצווה

בקשה באצווה מורכבת ממספר קריאות ל-API שמשולבות בבקשת HTTP אחת, וניתן לשלוח אותן אל batchPath שצוין במסמך גילוי ה-API. נתיב ברירת המחדל הוא /batch/api_name/api_version. בקטע הזה נתאר בפירוט את התחביר של הקבוצות. בהמשך, הנה דוגמה.

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

הפורמט של בקשה באצווה

בקשה באצווה היא בקשת HTTP רגילה יחידה שמכילה מספר קריאות ל-API של Gmail, מסוג התוכן multipart/mixed. בבקשת ה-HTTP הראשית הזו, כל אחד מהחלקים מכיל בקשת HTTP מקננת.

כל חלק מתחיל בכותרת HTTP Content-Type: application/http משלו. אפשר גם לקבל כותרת Content-ID אופציונלית. עם זאת, כותרות החלקים מופיעות רק כדי לסמן את תחילת החלק. הן נפרדות מהבקשה המקוננת. לאחר שהשרת פותח את האריזה של הבקשה באצווה לבקשות נפרדות, המערכת מתעלמת מכותרות החלקים.

הגוף של כל חלק הוא בקשת HTTP מלאה, עם פועל, כתובת URL, כותרות וגוף משלו. בקשת ה-HTTP חייבת להכיל רק את החלק של הנתיב בכתובת ה-URL. לא ניתן להשתמש בכתובות URL מלאות בבקשות באצווה.

כותרות ה-HTTP של בקשת האצווה החיצונית, מלבד הכותרות Content- (כמו Content-Type), חלות על כל הבקשות בקבוצה. אם מציינים כותרת HTTP נתונה גם בבקשה החיצונית וגם בקריאה הבודדת, הערך של כותרת הקריאה המסוימת מבטל את הערך של הכותרת החיצונית של הבקשה באצווה. הכותרות של שיחה ספציפית חלות רק על אותה שיחה.

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

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

תשובה לבקשה באצווה

תגובת השרת היא תגובת HTTP רגילה אחת עם סוג תוכן multipart/mixed. כל חלק הוא תגובה לאחת מהבקשות בבקשה המקובצת, באותו סדר שבו הן מופיעות בבקשות.

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

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

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

דוגמה

בדוגמה הבאה אפשר לראות את השימוש בקיבוץ ב-API של הדגמה כללית (דמיוני) שנקרא Fact API. עם זאת, אותם מושגים חלים גם על ממשק ה-API של Gmail.

בקשה לדוגמה באצווה

POST /batch/farm/v1 HTTP/1.1
Authorization: Bearer your_auth_token
Host: www.googleapis.com
Content-Type: multipart/mixed; boundary=batch_foobarbaz
Content-Length: total_content_length

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item1:12930812@barnyard.example.com>

GET /farm/v1/animals/pony

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item2:12930812@barnyard.example.com>

PUT /farm/v1/animals/sheep
Content-Type: application/json
Content-Length: part_content_length
If-Match: "etag/sheep"

{
  "animalName": "sheep",
  "animalAge": "5"
  "peltColor": "green",
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <item3:12930812@barnyard.example.com>

GET /farm/v1/animals
If-None-Match: "etag/animals"

--batch_foobarbaz--

דוגמה לתשובה באצווה

זו התגובה לבקשה לדוגמה שבקטע הקודם.

HTTP/1.1 200
Content-Length: response_total_content_length
Content-Type: multipart/mixed; boundary=batch_foobarbaz

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item1:12930812@barnyard.example.com>

HTTP/1.1 200 OK
Content-Type application/json
Content-Length: response_part_1_content_length
ETag: "etag/pony"

{
  "kind": "farm#animal",
  "etag": "etag/pony",
  "selfLink": "/farm/v1/animals/pony",
  "animalName": "pony",
  "animalAge": 34,
  "peltColor": "white"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item2:12930812@barnyard.example.com>

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: response_part_2_content_length
ETag: "etag/sheep"

{
  "kind": "farm#animal",
  "etag": "etag/sheep",
  "selfLink": "/farm/v1/animals/sheep",
  "animalName": "sheep",
  "animalAge": 5,
  "peltColor": "green"
}

--batch_foobarbaz
Content-Type: application/http
Content-ID: <response-item3:12930812@barnyard.example.com>

HTTP/1.1 304 Not Modified
ETag: "etag/animals"

--batch_foobarbaz--