שיטות מומלצות לשימוש בשירותי האינטרנט של Places Insights API

שירותי האינטרנט של פלטפורמת מפות Google הם אוסף של ממשקי HTTP לשירותי Google שמספקים נתונים גיאוגרפיים לאפליקציות המפות שלכם.

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

מהו שירות אינטרנט?

שירותי האינטרנט של הפלטפורמה של מפות Google הם ממשק לבקשת נתונים מ-Maps API משירותים חיצוניים ולהשתמש בנתונים באפליקציות של מפות Google. השירותים האלה מיועדים לשימוש בשילוב עם מפה, בהתאם להגבלות הרישיון שמפורטות בתנאים ובהגבלות של פלטפורמת מפות Google.

שירותי האינטרנט של Maps API משתמשים בבקשות HTTP(S) לכתובות URL ספציפיות, ומעבירים לשירותים פרמטרים של כתובות URL ו/או נתוני POST בפורמט JSON כארגומנטים. בדרך כלל, השירותים האלה מחזירים נתונים בגוף התגובה כ-JSON לניתוח ו/או לעיבוד על ידי האפליקציה.

בדוגמה הבאה מוצגת כתובת ה-URL של בקשת GET ב-REST:

AN ACTUAL API CALL INCLUDING THE API_KEY&key=API_KEY

הערה: כל האפליקציות של Places Insights API מחייבות אימות. מידע נוסף על פרטי כניסה לאימות

גישה ל-SSL/TLS

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

יצירת כתובת URL תקינה

יכול להיות שתחשובו שכתובת URL 'תקפה' היא מובנת מאליו, אבל זה לא בדיוק המצב. לדוגמה, כתובת URL שמזינים בסרגל הכתובות בדפדפן עשויה להכיל תווים מיוחדים (למשל "上海+中國"). הדפדפן צריך לתרגם את התווים האלה באופן פנימי לקידוד אחר לפני ההעברה. באופן דומה, כל קוד שיוצר או מקבל קלט ב-UTF-8 עשוי להתייחס לכתובות URL עם תווים ב-UTF-8 כ'תקינות', אבל יהיה עליו גם לתרגם את התווים האלה לפני השליחה שלהם לשרת אינטרנט. התהליך הזה נקרא קידוד כתובות URL או קידוד לפי אחוזים.

תווים מיוחדים

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

סיכום של התווים שמותר להשתמש בהם בכתובות URL
אפשר להתחיל?תוויםשימוש בכתובת URL
אלפאנומרי a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 מחרוזות טקסט, שימוש בסכימה (http), יציאה (8080) וכו'.
לא שמור - _ . ~ מחרוזות טקסט
בוצעה הזמנה ! * ' ( ) ; : @ & = + $ , / ? % # [ ] תווי בקרה ו/או מחרוזות טקסט

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

  • התווים שרוצים לטפל בהם לא נמצאים בקבוצה שלמעלה. לדוגמה, תווים בשפות זרות, כמו 上海+中國, צריך לקודד באמצעות התווים שלמעלה. לפי הסכמה פופולרית, לעיתים קרובות רווחים (שאסור להשתמש בהם בכתובות URL) מיוצגים גם באמצעות התו '+'.
  • התווים נמצאים בקבוצה שלמעלה בתור תווים שמורים, אבל צריך להשתמש בהם באופן מילולי. לדוגמה, התו ? משמש בכתובות URL כדי לציין את תחילת מחרוזת השאילתה. אם רוצים להשתמש במחרוזת '? and the Mysterions', צריך לקודד את התו '?'.

כל התווים שצריך לקודד בהתאמה לכתובות URL מקודדים באמצעות התו '%' וערך הקסדצימלי בן שני תווים שתואם לתו ה-UTF-8 שלהם. לדוגמה, 上海+中國 ב-UTF-8 יותאם לקידודי התווים שמתאימים לכתובות URL באופן הבא: %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B. המחרוזת ? and the Mysterians יותאמו לקידודי התווים שמתאימים לכתובות URL באופן הבא: %3F+and+the+Mysterians או %3F%20and%20the%20Mysterians.

תווים נפוצים שצריך לקודד

דוגמאות לתוים נפוצים שצריך לקודד:

תו לא בטוח ערך מקודד
רווח %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

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

בנוסף, כתובות URL מוגבלות ל-16,384 תווים בכל שירותי האינטרנט של הפלטפורמה של מפות Google וממשקי ה-API הסטטיים של האינטרנט. ברוב השירותים, מגבלת התווים הזו תהיה גדולה מדי. עם זאת, חשוב לזכור שלשירותים מסוימים יש כמה פרמטרים שעשויים לגרום לכתובות URL ארוכות.

שימוש מנומס ב-Google APIs

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

השהיה מעריכית לפני ניסיון חוזר (exponential backoff)

במקרים נדירים, יכול להיות משהו השתבש בטיפול בבקשה. יכול להיות שתקבלו קוד תגובה HTTP‏ 4XX או 5XX, או שפשוט החיבור ל-TCP נכשל במקום כלשהו בין הלקוח שלכם לשרת של Google. לרוב כדאי לנסות שוב את הבקשה, כי ייתכן שהבקשה הבאה תצליח אם הבקשה המקורית נכשלה. עם זאת, חשוב לא לשלוח בקשות שוב ושוב לשרתים של Google. התנהגות הלולאה הזו עלולה לגרום לעומס ברשת בין הלקוח ל-Google, וכתוצאה מכך לבעיות אצל גורמים רבים.

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

לדוגמה, נניח שאפליקציה רוצה לשלוח את הבקשה הבאה ל-Time Zone API:

https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=1331161200&key=YOUR_API_KEY

בדוגמה הבאה ב-Python מוסבר איך לשלוח את הבקשה עם השהיה מעריכית לפני ניסיון חוזר (exponential backoff):

import json
import time
import urllib.error
import urllib.parse
import urllib.request

# The maps_key defined below isn't a valid Google Maps API key.
# You need to get your own API key.
# See https://developers.google.com/maps/documentation/timezone/get-api-key
API_KEY = "YOUR_KEY_HERE"
TIMEZONE_BASE_URL = "https://maps.googleapis.com/maps/api/timezone/json"


def timezone(lat, lng, timestamp):

    # Join the parts of the URL together into one string.
    params = urllib.parse.urlencode(
        {"location": f"{lat},{lng}", "timestamp": timestamp, "key": API_KEY,}
    )
    url = f"{TIMEZONE_BASE_URL}?{params}"

    current_delay = 0.1  # Set the initial retry delay to 100ms.
    max_delay = 5  # Set the maximum retry delay to 5 seconds.

    while True:
        try:
            # Get the API response.
            response = urllib.request.urlopen(url)
        except urllib.error.URLError:
            pass  # Fall through to the retry loop.
        else:
            # If we didn't get an IOError then parse the result.
            result = json.load(response)

            if result["status"] == "OK":
                return result["timeZoneId"]
            elif result["status"] != "UNKNOWN_ERROR":
                # Many API errors cannot be fixed by a retry, e.g. INVALID_REQUEST or
                # ZERO_RESULTS. There is no point retrying these requests.
                raise Exception(result["error_message"])

        if current_delay > max_delay:
            raise Exception("Too many retry attempts.")

        print("Waiting", current_delay, "seconds before retrying.")

        time.sleep(current_delay)
        current_delay *= 2  # Increase the delay each time we retry.


if __name__ == "__main__":
    tz = timezone(39.6034810, -119.6822510, 1331161200)
    print(f"Timezone: {tz}")

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

בקשות מסונכרנות

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

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

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

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

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

עיבוד התשובות

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

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

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