שיטות מומלצות לשימוש בשירותי האינטרנט של Map Tiles API

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

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

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

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

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

דוגמה לבקשה לשירות אינטרנט היא בקשה למטא-נתונים של Street View, שנראית כך:

https://tile.googleapis.com/v1/streetview/metadata?session=YOUR_SESSION_TOKEN&key=YOUR_API_KEY&panoId=panoId

הערה: כל האפליקציות של Map Tiles API דורשות אימות. מידע נוסף על פרטי כניסה לאימות

גישה ל-SSL/TLS

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

שימוש הוגן ב-Google APIs

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

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

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

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

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

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

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

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

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

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

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