שיפור הביצועים

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

דוגמה

תיקון (עדכון חלקי)

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

בדוגמה הקצרה שלמטה אפשר לראות איך שימוש ב-patch מצמצם את כמות הנתונים שצריך לשלוח כדי לבצע עדכון קטן.

דוגמה

טיפול בתשובה לתיקון

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

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

בקשות באצווה

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

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

סקירה כללית

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

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

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

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

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

הערה: מערכת הקריאות באצווה של Google Drive API משתמשת בתחביר זהה לזה של מערכת העיבוד ברצף (batch processing) של OData, אבל הסמנטיקה שלהן שונה.

אילוצים נוספים:

  • בקשות באצווה עם יותר מ-100 קריאות עלולות לגרום לשגיאה.
  • אורך כתובת ה-URL של כל בקשה פנימית מוגבל ל-8,000 תווים.
  • ‫Google Drive לא תומך בפעולות אצווה למדיה, לא להעלאה או להורדה ולא לייצוא קבצים.

פירוט לגבי בקשות באצווה

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

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

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

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

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

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

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

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

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

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

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

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

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

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

דוגמה

בדוגמה הבאה מוצג שימוש באוסף פעולות עם Google Drive API.

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

POST https://www.googleapis.com/batch/drive/v3
Accept-Encoding: gzip
User-Agent: Google-HTTP-Java-Client/1.20.0 (gzip)
Content-Type: multipart/mixed; boundary=END_OF_PART
Content-Length: 963

--END_OF_PART Content-Length: 337 Content-Type: application/http content-id: 1 content-transfer-encoding: binary

POST https://www.googleapis.com/drive/v3/files/fileId/permissions?fields=id Authorization: Bearer authorization_token Content-Length: 70 Content-Type: application/json; charset=UTF-8

{ "emailAddress":"example@appsrocks.com", "role":"writer", "type":"user" } --END_OF_PART Content-Length: 353 Content-Type: application/http content-id: 2 content-transfer-encoding: binary

POST https://www.googleapis.com/drive/v3/files/fileId/permissions?fields=id&sendNotificationEmail=false Authorization: Bearer authorization_token Content-Length: 58 Content-Type: application/json; charset=UTF-8

{ "domain":"appsrocks.com", "role":"reader", "type":"domain" } --END_OF_PART--

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

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

HTTP/1.1 200 OK
Alt-Svc: quic=":443"; p="1"; ma=604800
Server: GSE
Alternate-Protocol: 443:quic,p=1
X-Frame-Options: SAMEORIGIN
Content-Encoding: gzip
X-XSS-Protection: 1; mode=block
Content-Type: multipart/mixed; boundary=batch_6VIxXCQbJoQ_AATxy_GgFUk
Transfer-Encoding: chunked
X-Content-Type-Options: nosniff
Date: Fri, 13 Nov 2015 19:28:59 GMT
Cache-Control: private, max-age=0
Vary: X-Origin
Vary: Origin
Expires: Fri, 13 Nov 2015 19:28:59 GMT

--batch_6VIxXCQbJoQ_AATxy_GgFUk Content-Type: application/http Content-ID: response-1

HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Date: Fri, 13 Nov 2015 19:28:59 GMT Expires: Fri, 13 Nov 2015 19:28:59 GMT Cache-Control: private, max-age=0 Content-Length: 35

{ "id": "12218244892818058021i" }

--batch_6VIxXCQbJoQ_AATxy_GgFUk Content-Type: application/http Content-ID: response-2

HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Date: Fri, 13 Nov 2015 19:28:59 GMT Expires: Fri, 13 Nov 2015 19:28:59 GMT Cache-Control: private, max-age=0 Content-Length: 35

{ "id": "04109509152946699072k" }

--batch_6VIxXCQbJoQ_AATxy_GgFUk--

החזרת שדות ספציפיים מהבקשה

אם לא מציינים את הפרמטר fields, השרת מחזיר קבוצת ברירת מחדל של שדות שספציפיים לשיטה. לדוגמה, השיטה files.list מחזירה רק את השדות kind, id, name ו-mimeType.

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

בכל השיטות של המשאבים about, ‏ comments (לא כולל delete) ו-replies (לא כולל delete), חובה להגדיר את הפרמטר fields. השיטות האלה לא מחזירות קבוצת שדות שמוגדרת כברירת מחדל.