במסמך הזה מפורטות כמה טכניקות שיעזרו לכם לשפר את ביצועי האפליקציה. במקרים מסוימים אנחנו משתמשים בדוגמאות מממשקי API אחרים או מממשקי API כלליים כדי להמחיש את הרעיונות שמוצגים. עם זאת, אותם מושגים חלים גם על Directory API.
דחיסה באמצעות gzip
דרך קלה ונוחה לצמצם את רוחב הפס הדרוש לכל בקשה היא לאפשר דחיסת gzip. למרות שהפעולה הזו דורשת זמן נוסף של המעבד (CPU) כדי לבטל את הדחיסה של התוצאות, היא משתלמת מאוד בזכות הצמצום בעלויות של הרשת.
כדי לקבל תשובה בקידוד gzip, עליך לעשות שני דברים: להגדיר כותרת Accept-Encoding
ולשנות את סוכן המשתמש כך שיכלול את המחרוזת gzip
. לפניכם דוגמה לכותרות HTTP במבנה תקין שמאפשרות דחיסת gzip:
Accept-Encoding: gzip User-Agent: my program (gzip)
עבודה עם משאבים חלקיים
דרך נוספת לשפר את הביצועים של הקריאות ל-API היא לשלוח ולקבל רק את חלק הנתונים הרצוי. כך האפליקציה לא תוכל להעביר, לנתח ולאחסן שדות שאין בהם צורך, וכך להשתמש במשאבים כולל רשת, מעבד (CPU) וזיכרון בצורה יעילה יותר.
יש שני סוגים של בקשות חלקיות:
- תגובה חלקית: בקשה שבה מציינים אילו שדות יש לכלול בתגובה (באמצעות פרמטר הבקשה
fields
). - תיקון: בקשת עדכון שבה שולחים רק את השדות שרוצים לשנות (יש להשתמש בפועל
PATCH
של HTTP).
בקטעים הבאים יש פרטים נוספים על שליחת בקשות חלקיות.
תשובה חלקית
כברירת מחדל, השרת שולח חזרה ייצוג מלא של משאב אחרי עיבוד הבקשות. לשיפור הביצועים, תוכלו לבקש מהשרת לשלוח רק את השדות שאתם צריכים באמת ולקבל במקום זאת תגובה חלקית.
כדי לבקש תשובה חלקית, צריך להשתמש בפרמטר הבקשה 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
. כדי לבחור שדהc
בתוךb
צריך להשתמש בפונקציהa/b/c
.
חריג: בתגובות API שמשתמשות ברכיבי wrapper של "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
חייב להיות מקודד בכתובת ה-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
, הוא שולח חזרה קוד סטטוס HTTP 200 OK
יחד עם הנתונים המבוקשים. אם יש שגיאה בפרמטר של השאילתה 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
, למשל), כדאי להשתמש בפרמטרים האלה כדי לצמצם את התוצאות של כל שאילתה לגודל שניתן לניהול. אחרת, ייתכן שהביצועים ישיגו ביצועים חלקיים כי הם לא ייושמו.
תיקון (עדכון חלקי)
אפשר גם להימנע משליחת נתונים מיותרים כשמשנים משאבים. כדי לשלוח נתונים מעודכנים רק בשדות הספציפיים שאתם משנים, צריך להשתמש בפועל PATCH
של HTTP. סמנטיקה של תיקונים המתוארת במסמך הזה שונה (ופשוטה יותר) בהשוואה להטמעה הקודמת של GData של עדכון חלקי.
הדוגמה הקצרה הבאה מראה איך השימוש בתיקון מצמצם את הנתונים שצריך לשלוח כדי לבצע עדכון קטן.
דוגמה
בדוגמה הזו מוצגת בקשת תיקון פשוטה כדי לעדכן רק את השם של משאב API כללי (דמיוני) "הדגמה". למשאב יש גם תגובה, קבוצת מאפיינים, סטטוס ושדות רבים אחרים, אבל הבקשה הזו שולחת רק את השדה 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, השתמשו במקום זאת ב-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
אם חומת האש לא מאפשרת בקשות PATCH
HTTP, צריך לבצע בקשת HTTP POST
ולהגדיר את כותרת הביטול כ-PATCH
, כפי שמוצג בהמשך:
POST https://www.googleapis.com/... X-HTTP-Method-Override: PATCH ...
ההבדל בין תיקון לעדכון
בפועל, כששולחים נתונים לבקשת עדכון עם פועל PUT
של HTTP, צריך לשלוח רק את השדות האלה, שהם שדות חובה או שדות אופציונליים. אם שולחים ערכים לשדות שהוגדרו על ידי השרת, המערכת מתעלמת מהם. נראה שזו דרך נוספת לבצע עדכון חלקי, אבל לגישה הזו יש כמה מגבלות. בעדכונים שמשתמשים בפועל PUT
של HTTP, הבקשה תיכשל אם לא תספקו את הפרמטרים הנדרשים. אם לא תספקו פרמטרים אופציונליים, הנתונים שהוגדרו בעבר יימחקו.
לכן בטוח יותר להשתמש בתיקון. עליכם לספק נתונים רק לשדות שאתם רוצים לשנות. שדות שתשמיט לא יימחקו. היוצא מן הכלל היחיד לכלל זה מתרחש באלמנטים או מערכים שחוזרים על עצמם: אם משמיטים את כולם, הם נשארים כפי שהם. אם תוסיפו אף אחד מהם, הקבוצה כולה תוחלף בקבוצה שתספקו.