Blogger JSON API: טיפים לשיפור הביצועים

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

דחיסה באמצעות 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 גנרי (בדיוני) "Demo" 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 שנעשה בהן שימוש ב-"data" 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 חייב להיות מקודד בכתובת ה-URL. כדי שהניסוח יהיה קריא יותר, הדוגמאות שבמסמך הזה הושמטו.

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

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

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

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

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

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