במסמך הזה מפורטות כמה טכניקות שיעזרו לכם לשפר את הביצועים של האפליקציה. בחלק מהמקרים, נעשה שימוש בדוגמאות מממשקי API אחרים או מממשקי API כלליים כדי להמחיש את הרעיונות שמוצגים. עם זאת, אותם מושגים רלוונטיים גם ל-Gmail API.
דחיסה באמצעות gzip
דרך קלה ונוחה לצמצם את רוחב הפס הדרוש לכל בקשה היא להפעיל דחיסת נתונים מסוג gzip. על אף שהפעולה הזו דורשת זמן CPU (מעבד) נוסף כדי לבטל את הדחיסה של התוצאות, היא משתלמת מאוד בזכות הצמצום בעלויות של הרשת.
כדי לקבל תשובה עם קידוד gzip, צריך לבצע שני דברים: להגדיר כותרת Accept-Encoding ולשנות את סוכן המשתמש כך שיכיל את המחרוזת gzip. דוגמה לכותרות HTTP שנוצרו בצורה תקינה כדי להפעיל דחיסת gzip:
Accept-Encoding: gzip User-Agent: my program (gzip)
עבודה עם משאבים חלקיים
דרך נוספת לשפר את הביצועים של הקריאות ל-API היא לשלוח ולקבל רק את החלק של הנתונים שמעניין אתכם. כך האפליקציה לא צריכה להעביר, לנתח ולאחסן שדות לא נחוצים, והיא יכולה להשתמש במשאבים, כולל רשת, מעבד וזיכרון, בצורה יעילה יותר.
יש שני סוגים של בקשות חלקיות:
- תגובה חלקית: בקשה שבה מציינים אילו שדות לכלול בתגובה (משתמשים בפרמטר הבקשה
fields). - Patch: בקשת עדכון שבה שולחים רק את השדות שרוצים לשנות (משתמשים בפועל HTTP
PATCH).
פרטים נוספים על שליחת בקשות חלקיות מפורטים בקטעים הבאים.
תשובה חלקית
כברירת מחדל, השרת שולח בחזרה את הייצוג המלא של משאב אחרי עיבוד הבקשות. כדי לשפר את הביצועים, אפשר לבקש מהשרת לשלוח רק את השדות שבאמת צריכים ולקבל במקום זאת תגובה חלקית.
כדי לבקש תגובה חלקית, משתמשים בפרמטר הבקשה fields כדי לציין את השדות שרוצים להחזיר. אפשר להשתמש בפרמטר הזה בכל בקשה שמחזירה נתוני תגובה.
שימו לב שהפרמטר fields משפיע רק על נתוני התגובה, ולא על הנתונים שצריך לשלוח, אם יש כאלה. כדי להקטין את כמות הנתונים שאתם שולחים כשאתם משנים משאבים, כדאי להשתמש בבקשת patch.
דוגמה
בדוגמה הבאה מוצג שימוש בפרמטר fields עם API כללי (פיקטיבי) בשם Demo.
בקשה פשוטה: בבקשת ה-HTTP GET הזו, הפרמטר fields מושמט והמשאב המלא מוחזר.
https://www.googleapis.com/demo/v1
תשובה מלאה של משאב: נתוני המשאב המלאים כוללים את השדות הבאים, וגם שדות רבים אחרים שהושמטו כדי שהתשובה תהיה קצרה יותר.
{
"kind": "demo",
...
"items": [
{
"title": "First title",
"comment": "First comment.",
"characteristics": {
"length": "short",
"accuracy": "high",
"followers": ["Jo", "Will"],
},
"status": "active",
...
},
{
"title": "Second title",
"comment": "Second comment.",
"characteristics": {
"length": "long",
"accuracy": "medium"
"followers": [ ],
},
"status": "pending",
...
},
...
]
}בקשה לתגובה חלקית: הבקשה הבאה לאותו משאב משתמשת בפרמטר fields כדי לצמצם באופן משמעותי את כמות הנתונים שמוחזרת.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
תגובה חלקית: בתגובה לבקשה שלמעלה, השרת מחזיר תגובה שמכילה רק את פרטי הסוג, יחד עם מערך פריטים מצומצם שכולל רק את שם ה-HTML ופרטי אורך בכל פריט.
200 OK
{
"kind": "demo",
"items": [{
"title": "First title",
"characteristics": {
"length": "short"
}
}, {
"title": "Second title",
"characteristics": {
"length": "long"
}
},
...
]
}התגובה היא אובייקט JSON שכולל רק את השדות שנבחרו ואת אובייקטי ההורה שמקיפים אותם.
בקטע הבא מוסבר איך להגדיר את הפרמטר fields, ולאחר מכן מפורט מה בדיוק מוחזר בתשובה.
סיכום תחביר של פרמטר השדות
הפורמט של ערך הפרמטר fields בבקשה מבוסס באופן חלקי על תחביר XPath. בקטע הבא מופיע סיכום של התחביר הנתמך ודוגמאות נוספות.
- כדי לבחור כמה שדות, צריך להשתמש ברשימה של שדות שמופרדים באמצעות פסיקים.
- משתמשים ב-
a/bכדי לבחור שדהbשמוטמע בשדהa, ומשתמשים ב-a/b/cכדי לבחור שדהcשמוטמע בשדהb.
יוצא מן הכלל: בתגובות ל-API שמשתמשות במעטפות 'data', שבהן התגובה מוטמעת באובייקט
dataשנראה כמוdata: { ... }, אל תכללו אתdataבמפרטfields. הכללת אובייקט הנתונים עם מפרט שדות כמוdata/a/bגורמת לשגיאה. במקום זאת, פשוט משתמשים במפרטfieldsכמוa/b. - כדי לבקש קבוצה של שדות משנה ספציפיים של מערכים או אובייקטים, משתמשים בבורר משנה ומציבים ביטויים בתוך סוגריים "
( )".לדוגמה:
fields=items(id,author/email)מחזירה רק את מזהה הפריט ואת כתובת האימייל של המחבר לכל רכיב במערך הפריטים. אפשר גם לציין שדה משנה יחיד, כאשרfields=items(id)שווה ל-fields=items/id. - אם צריך, אפשר להשתמש בתווים כלליים לחיפוש בבחירות של השדות.
לדוגמה:
fields=items/pagemap/*בוחר את כל האובייקטים במפת הדפים.
דוגמאות נוספות לשימוש בפרמטר fields
בדוגמאות שלמטה מפורט איך הערך של הפרמטר fields משפיע על התגובה.
הערה: כמו כל ערכי הפרמטרים של השאילתה, ערך הפרמטר fields חייב להיות מקודד בכתובת ה-URL. כדי שהדוגמאות במסמך הזה יהיו קלות יותר לקריאה, השמטנו את הקידוד.
- מזהים את השדות שרוצים לקבל או בוחרים שדות.
- הערך של פרמטר הבקשה
fieldsהוא רשימה של שדות שמופרדים בפסיקים, וכל שדה מצוין ביחס לשורש של התגובה. לכן, אם מבצעים פעולת list, התגובה היא אוסף, ובדרך כלל היא כוללת מערך של משאבים. אם מבצעים פעולה שמחזירה משאב יחיד, השדות מצוינים ביחס למשאב הזה. אם השדה שנבחר הוא מערך (או חלק ממערך), השרת מחזיר את החלק שנבחר מכל הרכיבים במערך.
הנה כמה דוגמאות ברמת האוסף:
דוגמאות השפעה itemsמחזירה את כל הרכיבים במערך הפריטים, כולל כל השדות בכל רכיב, אבל לא שדות אחרים. etag,itemsהפונקציה מחזירה גם את השדה etagוגם את כל הרכיבים במערך הפריטים.items/titleהפונקציה מחזירה רק את השדה titleלכל הרכיבים במערך הפריטים.
בכל פעם שמוחזר שדה מקונן, התגובה כוללת את אובייקטי ההורה המקיפים. שדות ההורה לא כוללים שדות צאצא אחרים, אלא אם הם נבחרו במפורש.context/facets/labelהפונקציה מחזירה רק את השדה labelלכל החברים במערךfacets, שמוטמע בעצמו באובייקטcontext.items/pagemap/*/titleלכל רכיב במערך הפריטים, הפונקציה מחזירה רק את השדה title(אם הוא קיים) של כל האובייקטים שהם צאצאים שלpagemap.
הנה כמה דוגמאות ברמת המשאב:
דוגמאות השפעה titleמחזירה את השדה titleשל המשאב המבוקש.author/uriמחזירה את שדה המשנה uriשל האובייקטauthorבמשאב המבוקש.links/*/hrefהפונקציה מחזירה את השדה hrefשל כל האובייקטים שהם צאצאים שלlinks. - אפשר לבקש רק חלקים משדות ספציפיים באמצעות בחירות משניות.
- כברירת מחדל, אם בבקשה שלכם מצוינים שדות מסוימים, השרת מחזיר את האובייקטים או את רכיבי המערך בשלמותם. אתם יכולים לציין תגובה שתכלול רק שדות משנה מסוימים. כדי לעשות את זה, משתמשים בתחביר של בחירת משנה
( ), כמו בדוגמה שלמטה.דוגמה השפעה items(title,author/uri)הפונקציה מחזירה רק את הערכים של titleושלuriשל המחבר לכל רכיב במערך הפריטים.
טיפול בתשובות חלקיות
אחרי ששרת מעבד בקשה תקינה שכוללת את פרמטר השאילתה fields, הוא מחזיר קוד סטטוס 200 OK של HTTP, יחד עם הנתונים המבוקשים. אם יש שגיאה בפרמטר השאילתה fields או שהוא לא תקין מסיבה אחרת, השרת מחזיר קוד סטטוס HTTP 400 Bad Request, יחד עם הודעת שגיאה שמסבירה למשתמש מה לא בסדר בבחירת השדות שלו (לדוגמה, "Invalid field selection a/b").
זוהי דוגמה לתשובה חלקית שמופיעה בקטע המבוא שלמעלה. הבקשה משתמשת בפרמטר fields כדי לציין אילו שדות להחזיר.
https://www.googleapis.com/demo/v1?fields=kind,items(title,characteristics/length)
התגובה החלקית נראית כך:
200 OK
{
"kind": "demo",
"items": [{
"title": "First title",
"characteristics": {
"length": "short"
}
}, {
"title": "Second title",
"characteristics": {
"length": "long"
}
},
...
]
}הערה: בממשקי API שתומכים בפרמטרים של שאילתות להחלפת דפים של נתונים (למשל maxResults ו-nextPageToken), כדאי להשתמש בפרמטרים האלה כדי לצמצם את התוצאות של כל שאילתה לגודל שקל לנהל. אחרת, יכול להיות שלא תהיה עלייה בביצועים כמו במקרים שבהם נעשה שימוש בתגובה חלקית.
תיקון (עדכון חלקי)
בנוסף, אפשר להימנע משליחת נתונים מיותרים כשמשנים משאבים. כדי לשלוח נתונים מעודכנים רק לשדות הספציפיים שאתם משנים, משתמשים בפועל HTTP PATCH. הסמנטיקה של תיקוני ה-patch שמתוארת במסמך הזה שונה (ופשוטה יותר) מזו שהייתה בגרסה הקודמת של GData, שבה נעשה שימוש בעדכון חלקי.
בדוגמה הקצרה שלמטה אפשר לראות איך שימוש ב-patch מצמצם את כמות הנתונים שצריך לשלוח כדי לבצע עדכון קטן.
דוגמה
בדוגמה הזו מוצגת בקשת תיקון פשוטה לעדכון רק הכותרת של משאב API כללי (פיקטיבי) בשם Demo. למשאב יש גם תגובה, קבוצת מאפיינים, סטטוס ועוד הרבה שדות אחרים, אבל הבקשה הזו שולחת רק את השדה title, כי זה השדה היחיד שמשתנה:
PATCH https://www.googleapis.com/demo/v1/324
Authorization: Bearer your_auth_token
Content-Type: application/json
{
"title": "New title"
}תשובה:
200 OK
{
"title": "New title",
"comment": "First comment.",
"characteristics": {
"length": "short",
"accuracy": "high",
"followers": ["Jo", "Will"],
},
"status": "active",
...
}השרת מחזיר קוד סטטוס 200 OK, יחד עם הייצוג המלא של המשאב המעודכן. מכיוון שרק השדה title נכלל בבקשת התיקון, זה הערך היחיד ששונה מהערך הקודם.
הערה: אם משתמשים בפרמטר partial response fields בשילוב עם patch, אפשר לשפר עוד יותר את היעילות של בקשות העדכון. בקשת תיקון רק מקטינה את גודל הבקשה. תשובה חלקית מקטינה את גודל התשובה. לכן, כדי להפחית את כמות הנתונים שנשלחים לשני הכיוונים, כדאי להשתמש בבקשת תיקון עם הפרמטר fields.
הסמנטיקה של בקשת תיקון
גוף בקשת התיקון כולל רק את שדות המשאב שרוצים לשנות. כשמציינים שדה, צריך לכלול את כל אובייקטי ההורה המקיפים, בדיוק כמו שאובייקטי ההורה המקיפים מוחזרים עם תגובה חלקית. הנתונים ששלחתם אחרי השינוי ימוזגו עם הנתונים של אובייקט האב, אם יש כזה.
- הוספה: כדי להוסיף שדה שלא קיים, מציינים את השדה החדש ואת הערך שלו.
- שינוי: כדי לשנות את הערך של שדה קיים, מציינים את השדה ומגדירים לו את הערך החדש.
- מחיקה: כדי למחוק שדה, מציינים את השדה ומגדירים אותו לערך
null. לדוגמה,"comment": null. אפשר גם למחוק אובייקט שלם (אם הוא ניתן לשינוי) על ידי הגדרתו ל-null. אם אתם משתמשים בספריית הלקוח של Java API, אתם צריכים להשתמש ב-Data.NULL_STRINGבמקום זאת. פרטים נוספים זמינים במאמר בנושא JSON null.
הערה לגבי מערכים: בקשות תיקון (Patch) שמכילות מערכים מחליפות את המערך הקיים במערך שאתם מספקים. אי אפשר לשנות, להוסיף או למחוק פריטים במערך באופן חלקי.
שימוש ב-patch במחזור קריאה-שינוי-כתיבה
מומלץ להתחיל באחזור של תשובה חלקית עם הנתונים שרוצים לשנות. זה חשוב במיוחד למשאבים שמשתמשים ב-ETags, כי כדי לעדכן את המשאב בהצלחה צריך לספק את הערך הנוכחי של ה-ETag בכותרת ה-HTTP של If-Match. אחרי שמקבלים את הנתונים, אפשר לשנות את הערכים שרוצים לשנות ולשלוח את הייצוג החלקי ששונה בחזרה באמצעות בקשת תיקון. הנה דוגמה שבה ההנחה היא שמשאב ההדגמה משתמש ב-ETags:
GET https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics Authorization: Bearer your_auth_token
זו התשובה החלקית:
200 OK
{
"etag": "ETagString"
"title": "New title"
"comment": "First comment.",
"characteristics": {
"length": "short",
"level": "5",
"followers": ["Jo", "Will"],
}
}בקשת התיקון הבאה מבוססת על התגובה הזו. כמו שרואים בדוגמה הבאה, נעשה שימוש גם בפרמטר fields כדי להגביל את הנתונים שמוחזרים בתגובת התיקון:
PATCH https://www.googleapis.com/demo/v1/324?fields=etag,title,comment,characteristics Authorization: Bearer your_auth_token Content-Type: application/json If-Match: "ETagString"
{
"etag": "ETagString"
"title": "", /* Clear the value of the title by setting it to the empty string. */
"comment": null, /* Delete the comment by replacing its value with null. */
"characteristics": {
"length": "short",
"level": "10", /* Modify the level value. */
"followers": ["Jo", "Liz"], /* Replace the followers array to delete Will and add Liz. */
"accuracy": "high" /* Add a new characteristic. */
},
}השרת מגיב עם קוד סטטוס HTTP 200 OK, והייצוג החלקי של המשאב המעודכן:
200 OK
{
"etag": "newETagString"
"title": "", /* Title is cleared; deleted comment field is missing. */
"characteristics": {
"length": "short",
"level": "10", /* Value is updated.*/
"followers": ["Jo" "Liz"], /* New follower Liz is present; deleted Will is missing. */
"accuracy": "high" /* New characteristic is present. */
}
}יצירת בקשת תיקון ישירה
חלק מבקשות התיקון צריכות להתבסס על הנתונים שאוחזרו קודם. לדוגמה, אם רוצים להוסיף פריט למערך ולא רוצים לאבד אף אחד מהרכיבים הקיימים במערך, קודם צריך לאחזר את הנתונים הקיימים. באופן דומה, אם API משתמש ב-ETags, צריך לשלוח את ערך ה-ETag הקודם עם הבקשה כדי לעדכן את המשאב בהצלחה.
הערה: אפשר להשתמש ב"If-Match: *" כותרת HTTP כדי לאלץ תיקון לעבור כשמשתמשים ב-ETags. אם עושים את זה, לא צריך לבצע קריאה לפני הכתיבה.
במקרים אחרים, לעומת זאת, אפשר ליצור את בקשת התיקון ישירות, בלי לאחזר קודם את הנתונים הקיימים. לדוגמה, אתם יכולים להגדיר בקלות בקשת תיקון שמעדכנת שדה לערך חדש או מוסיפה שדה חדש. לדוגמה:
PATCH https://www.googleapis.com/demo/v1/324?fields=comment,characteristics
Authorization: Bearer your_auth_token
Content-Type: application/json
{
"comment": "A new comment",
"characteristics": {
"volume": "loud",
"accuracy": null
}
}אם בשדה ההערה יש ערך קיים, הערך החדש יחליף אותו. אחרת, הערך החדש יוגדר. באופן דומה, אם יש מאפיין של כרך, הערך שלו נכתב מחדש. אם אין מאפיין כזה, הוא נוצר. אם השדה 'דיוק' מוגדר, הוא מוסר.
טיפול בתשובה לתיקון
אחרי עיבוד של בקשת תיקון תקינה, ה-API מחזיר קוד תגובת HTTP 200 OK יחד עם הייצוג המלא של המשאב ששונה. אם ה-API משתמש ב-ETags, השרת מעדכן את ערכי ה-ETag כשהוא מעבד בהצלחה בקשת תיקון, בדיוק כמו שהוא עושה עם PUT.
בקשת התיקון מחזירה את כל ייצוג המשאב, אלא אם משתמשים בפרמטר fields כדי לצמצם את כמות הנתונים שהיא מחזירה.
אם בקשת תיקון מובילה למצב חדש של משאב שהוא לא חוקי מבחינת תחביר או סמנטיקה, השרת מחזיר קוד סטטוס HTTP 400 Bad Request או 422 Unprocessable Entity, ומצב המשאב נשאר ללא שינוי. לדוגמה, אם מנסים למחוק את הערך של שדה חובה, השרת מחזיר שגיאה.
סימון חלופי כשפועל ה-HTTP PATCH לא נתמך
אם חומת האש לא מאפשרת בקשות HTTP PATCH, צריך לשלוח בקשת HTTP POST ולהגדיר את כותרת ההחלפה ל-PATCH, כמו שמוצג בהמשך:
POST https://www.googleapis.com/... X-HTTP-Method-Override: PATCH ...
ההבדל בין תיקון לבין עדכון
בפועל, כששולחים נתונים לבקשת עדכון שמשתמשת בפועל HTTP PUT, צריך לשלוח רק את השדות הנדרשים או האופציונליים. אם שולחים ערכים לשדות שהוגדרו על ידי השרת, המערכת מתעלמת מהם. למרות שזה אולי נראה כמו דרך נוספת לעדכון חלקי, לגישה הזו יש כמה מגבלות. בעדכונים שמשתמשים בפועל ב-HTTP PUT, הבקשה נכשלת אם לא מספקים את הפרמטרים הנדרשים, והיא מוחקת נתונים שהוגדרו קודם אם לא מספקים פרמטרים אופציונליים.
לכן הרבה יותר בטוח להשתמש בתיקון. אתם מספקים נתונים רק לשדות שאתם רוצים לשנות. השדות שאתם משמיטים לא מתרוקנים. החריג היחיד לכלל הזה הוא כשמדובר ברכיבים חוזרים או במערכים: אם משמיטים את כולם, הם נשארים כמו שהם. אם מספקים חלק מהם, כל הקבוצה מוחלפת בקבוצה שסיפקתם.