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