במסמך הזה מפורטות כמה טכניקות שאפשר להשתמש בהן כדי לשפר את הביצועים של האפליקציה. במקרים מסוימים, נעשה שימוש בדוגמאות מממשקי API אחרים או מממשקי API כלליים כדי להמחיש את הרעיונות המוצגים. עם זאת, אותם מושגים רלוונטיים גם ל-Directory API.
דחיסה באמצעות gzip
דרך קלה ונוחה לצמצם את רוחב הפס הדרוש לכל בקשה היא להפעיל דחיסת נתונים מסוג gzip. על אף שהפעולה הזו דורשת זמן CPU (מעבד) נוסף כדי לבטל את הדחיסה של התוצאות, היא משתלמת מאוד בזכות הצמצום בעלויות של הרשת.
כדי לקבל תגובה בקידוד gzip, צריך לבצע שני דברים: להגדיר כותרת Accept-Encoding ולשנות את סוכן המשתמש כך שיכיל את המחרוזת gzip. דוגמה לכותרות HTTP בפורמט תקין להפעלת דחיסת gzip:
Accept-Encoding: gzip User-Agent: my program (gzip)
עבודה עם משאבים חלקיים
דרך נוספת לשפר את הביצועים של הקריאות ל-API היא לשלוח ולקבל רק את החלק של הנתונים שמעניין אתכם. כך האפליקציה יכולה להימנע מהעברה, מניתוח ומאחסון של שדות לא נחוצים, וכך היא יכולה להשתמש במשאבים, כולל רשת, מעבד (CPU) וזיכרון, בצורה יעילה יותר.
יש שני סוגים של בקשות חלקיות:
- תגובה חלקית: בקשה שבה מציינים אילו שדות לכלול בתגובה (משתמשים בפרמטר הבקשה
fields). - תיקון: בקשת עדכון שבה שולחים רק את השדות שרוצים לשנות (משתמשים בפעולה HTTP
PATCH).
פרטים נוספים על שליחת בקשות חלקיות מופיעים בקטעים הבאים.
מענה חלקי
כברירת מחדל, השרת שולח חזרה את הייצוג המלא של המשאב אחרי עיבוד הבקשות. כדי לשפר את הביצועים, אפשר לבקש מהשרת לשלוח רק את השדות שאתם באמת צריכים ולקבל במקום זאת תגובה חלקית.
כדי לבקש תשובה חלקית, צריך להשתמש בפרמטר הבקשה fields כדי לציין את השדות שרוצים שיוחזרו. אפשר להשתמש בפרמטר הזה בכל בקשה שמחזירה נתוני תגובה.
חשוב לזכור שהפרמטר fields משפיע רק על נתוני התגובה, ולא על הנתונים שצריך לשלוח, אם יש כאלה. כדי להפחית את כמות הנתונים שאתם שולחים כשמשנים משאבים, כדאי להשתמש בבקשת תיקון.
דוגמה
בדוגמה הבאה מוצג השימוש בפרמטר fields עם ממשק API 'דמו' גנרי (בדיוני).
בקשה פשוטה: בקשת ה-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 שמשתמשות ב-wrappers של 'נתונים', שבהן התגובה מוטמעת בתוך אובייקט
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.items/titleהפונקציה מחזירה רק את השדה titleלכל הרכיבים במערך הפריטים.
בכל פעם שמוחזר שדה בתצוגת עץ, התגובה כוללת את אובייקטי ההורה שמקפים אותו. שדות ההורה לא כוללים שדות צאצא אחרים, אלא אם הם נבחרו גם הם באופן מפורש.context/facets/labelהפונקציה מחזירה רק את השדה labelלכל המשתתפים במערךfacets, שהוא עצמו מוטמע באובייקטcontext.items/pagemap/*/titleלכל רכיב במערך items, הפונקציה מחזירה רק את השדה title(אם הוא קיים) של כל האובייקטים שהם צאצאים שלpagemap.
הנה כמה דוגמאות ברמת המשאב:
דוגמאות השפעה titleהפונקציה מחזירה את השדה titleשל המשאב המבוקש.author/uriהפונקציה מחזירה את שדה המשנה uriשל האובייקטauthorבמשאב המבוקש.links/*/hrefהפונקציה מחזירה את השדה hrefשל כל האובייקטים שהם צאצאים שלlinks. - לבקש רק חלקים של שדות ספציפיים באמצעות בחירות משנה.
- כברירת מחדל, אם הבקשה מציינת שדות מסוימים, השרת מחזיר את האובייקטים או את רכיבי המערך במלואם. אפשר לציין תשובה שכוללת רק שדות משנה מסוימים. כדי לעשות זאת, משתמשים בתחביר הבחירה המשנית '
( )', כמו בדוגמה הבאה.דוגמה השפעה items(title,author/uri)הפונקציה מחזירה רק את הערכים של titleושלuriשל המחבר לכל אלמנט במערך הפריטים.
טיפול בתשובות חלקיות
אחרי שהשרת מעבד בקשה תקינה שכוללת את פרמטר השאילתה fields, הוא שולח בחזרה קוד סטטוס HTTP 200 OK יחד עם הנתונים המבוקשים. אם יש שגיאה בפרמטר השאילתה fields או שהוא לא חוקי מסיבה אחרת, השרת מחזיר את קוד הסטטוס 400 Bad Request של HTTP, יחד עם הודעת שגיאה שמציינת למשתמש מה הבעיה בבחירת השדות שלו (לדוגמה, "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), צריך להשתמש בפרמטרים האלה כדי לצמצם את התוצאות של כל שאילתה לגודל שניתן לניהול. אחרת, יכול להיות שלא תראו את השיפורים בביצועים שאפשר להשיג באמצעות תגובה חלקית.
תיקון (עדכון חלקי)
אפשר גם להימנע משליחת נתונים מיותרים כשמשנים משאבים. כדי לשלוח נתונים מעודכנים רק לגבי השדות הספציפיים שאתם משנים, צריך להשתמש בפעולה PATCH של HTTP. הסמנטיקה של התיקון שמתוארת במסמך הזה שונה (ופשוטה יותר) מזו של ההטמעה הישנה יותר של GData לעדכון חלקי.
בדוגמה הקצרה שבהמשך מוצג איך שימוש בתיקון מקטין את כמות הנתונים שצריך לשלוח כדי לבצע עדכון קטן.
דוגמה
בדוגמה הזו מוצגת בקשת תיקון פשוטה לעדכון רק את הכותרת של משאב 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 נכלל בבקשת התיקון, זהו הערך היחיד ששונה מהערך הקודם.
הערה: אם משתמשים בפרמטר fields של תגובה חלקית בשילוב עם תיקון, אפשר לשפר עוד יותר את היעילות של בקשות העדכון. בקשת תיקון רק מקטינה את גודל הבקשה. מילוי חלקי של הטופס מקטין את גודל התשובה. לכן, כדי לצמצם את כמות הנתונים שנשלחים בשני הכיוונים, צריך להשתמש בבקשת תיקון עם הפרמטר fields.
הסמנטיקה של בקשת תיקון
גוף הבקשה לתיקון כולל רק את שדות המשאב שרוצים לשנות. כשמציינים שדה, צריך לכלול את כל אובייקטי ההורה המקיפים, בדיוק כמו שאובייקטי ההורה המקיפים מוחזרים עם תגובה חלקית. הנתונים ששונו ומועברים ימוזגו עם הנתונים של אובייקט ההורה, אם יש כזה.
- הוספה: כדי להוסיף שדה שלא קיים, מציינים את השדה החדש ואת הערך שלו.
- שינוי: כדי לשנות את הערך של שדה קיים, מציינים את השדה ומגדירים לו את הערך החדש.
- מחיקה: כדי למחוק שדה, מציינים את השדה ומגדירים אותו כ-
null. לדוגמה,"comment": null. אפשר גם למחוק אובייקט שלם (אם הוא ניתן לשינוי) על ידי הגדרתו ל-null. אם אתם משתמשים ב-Java API Client Library, צריך להשתמש ב-Data.NULL_STRINGבמקום זאת. פרטים נוספים זמינים במאמר JSON null.
הערה לגבי מערכים: בקשות תיקון שמכילות מערכים מחליפות את המערך הקיים במערך שסיפקתם. לא ניתן לשנות, להוסיף או למחוק פריטים במערך באופן חלקי.
שימוש בתיקון במחזור קריאה-שינוי-כתיבה
מומלץ להתחיל באחזור תשובה חלקית עם הנתונים שרוצים לשנות. זה חשוב במיוחד למשאבים שמשתמשים ב-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 הקודם עם הבקשה כדי לעדכן את המשאב בהצלחה.
הערה: אפשר להשתמש בכותרת HTTP "If-Match: *" כדי לאלץ תיקון לעבור כשנעשה שימוש ב-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 ...
מה ההבדל בין תיקון לבין עדכון
בפועל, כששולחים נתונים לבקשת עדכון שמשתמשת בפעולה PUT של HTTP, צריך לשלוח רק את השדות הנדרשים או האופציונליים. אם שולחים ערכים לשדות שהוגדרו על ידי השרת, הם יימחקו. יכול להיות שזה נראה כמו דרך נוספת לבצע עדכון חלקי, אבל לגישה הזו יש כמה מגבלות. בעדכונים שמשתמשים בפעולה PUT של HTTP, הבקשה נכשלת אם לא מספקים פרמטרים נדרשים, והיא מנקה נתונים שהוגדרו בעבר אם לא מספקים פרמטרים אופציונליים.
לכן, הרבה יותר בטוח להשתמש בתיקון. אתם מספקים נתונים רק לשדות שרוצים לשנות. שדות שלא תכללו לא יימחקו. החריג היחיד לכלל הזה הוא לגבי רכיבים או מערכי נתונים חוזרים: אם משמיטים את כולם, הם נשארים כפי שהם. אם מספקים אחד מהם, הקבוצה כולה מוחלפת בקבוצה שסיפקתם.