Best Practices für die Verwendung von Geolocation API-Webdiensten

Die Google Maps Platform-Webdienste sind eine Sammlung von HTTP-Schnittstellen zu Google-Diensten, über die geografische Daten für Ihre Kartenanwendungen bereitgestellt werden.

In diesem Leitfaden werden einige gängige Vorgehensweisen beschrieben, die beim Einrichten von Webdienstanfragen und Verarbeiten von Dienstantworten hilfreich sind. Im Entwicklerhandbuch findest du eine vollständige Dokumentation der Geolocation API.

Was ist ein Webdienst?

Google Maps Platform-Webdienste sind eine Schnittstelle, über die Sie Maps API-Daten von externen Diensten anfordern und in Ihren Maps-Anwendungen verwenden können. Diese Dienste sind für die Verwendung in Verbindung mit einer Karte gemäß den Lizenzbeschränkungen in den Nutzungsbedingungen der Google Maps Platform konzipiert.

Die Maps APIs-Webdienste verwenden HTTP(S)-Anfragen an bestimmte URLs und übergeben URL-Parameter und/oder POST-Daten im JSON-Format als Argumente an die Dienste. Im Allgemeinen geben diese Dienste Daten im Antworttext im JSON-Format zurück, um sie durch Ihre Anwendung zu parsen und/oder zu verarbeiten.

Geolocation-Anforderungen werden mit POST an die folgende URL gesendet:

https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY

Hinweis: Alle Geolocation API-Anwendungen erfordern eine Authentifizierung. Weitere Informationen zu Authentifizierungsdaten

SSL/TLS-Zugriff

HTTPS ist für alle Google Maps Platform-Anfragen erforderlich, die API-Schlüssel verwenden oder Nutzerdaten enthalten. Über HTTP erfolgte Anfragen mit sensiblen Daten werden möglicherweise abgelehnt.

Respektvolle Nutzung der Google APIs

Schlecht konzipierte API-Clients können sowohl das Internet als auch die Server von Google stärker als nötig belasten. Dieser Abschnitt enthält einige bewährte Methoden für Kunden der APIs. Mit diesen Best Practices können Sie verhindern, dass Ihre Anwendung aufgrund eines unbeabsichtigten Missbrauchs der APIs blockiert wird.

Exponentieller Backoff

In seltenen Fällen kann bei der Verarbeitung Ihrer Anfrage ein Fehler auftreten. Möglicherweise erhalten Sie einen HTTP-Antwortcode 4XX oder 5XX oder die TCP-Verbindung zwischen Ihrem Client und dem Google-Server schlägt fehl. Oft lohnt es sich, die Anfrage noch einmal zu senden, da die Folgeanfrage möglicherweise erfolgreich ist, wenn die ursprüngliche Anfrage fehlgeschlagen ist. Es ist jedoch wichtig, Anfragen nicht einfach in einer Schleife wiederholt an die Server von Google zu senden. Dieses Verhalten kann das Netzwerk zwischen Ihrem Client und Google überlasten und zu Problemen für viele Parteien führen.

Ein besserer Ansatz ist es, wiederholte Versuche in immer größeren Abständen durchzuführen. Normalerweise wird die Verzögerung bei jedem Versuch um einen multiplikativen Faktor erhöht. Dieser Ansatz wird als exponentieller Backoff bezeichnet.

Angenommen, eine Anwendung möchte diese Anfrage an die Time Zone API senden:

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

Im folgenden Beispiel mit Python wird gezeigt, wie die Anforderung mit exponentiellem Backoff durchgeführt wird:

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}")

Achten Sie außerdem darauf, dass es keinen Wiederholungscode weiter oben in der Anwendungsaufrufkette gibt, der zu wiederholten Anfragen in schneller Abfolge führt.

Synchronisierte Anforderungen

Eine große Anzahl synchronisierter Anfragen an die APIs von Google kann wie ein DDoS-Angriff (Distributed Denial of Service) auf die Infrastruktur von Google aussehen und entsprechend behandelt werden. Um dies zu vermeiden, sollten Sie darauf achten, dass API-Anfragen nicht zwischen Clients synchronisiert werden.

Angenommen, eine Anwendung zeigt die Zeit in der aktuellen Zeitzone an. Diese Anwendung wird wahrscheinlich einen Alarm im Client-Betriebssystem einstellen, durch den sie zu Beginn der Minute aktiviert wird, sodass die angezeigte Zeit aktualisiert werden kann. Die Anwendung sollte keine API-Aufrufe im Rahmen der Verarbeitung des Alarms ausführen.

API-Aufrufe als Reaktion auf einen festgelegten Alarm sind nicht gut, da sie dazu führen, dass die API-Aufrufe mit dem Anfang der Minute synchronisiert werden, auch zwischen verschiedenen Geräten, anstatt gleichmäßig über die Zeit verteilt zu werden. Eine schlecht konzipierte Anwendung, die dies tut, führt zu einer Traffic-Spitze mit einem 60-fachen Normalniveau zu Beginn jeder Minute.

Stattdessen wird bei einer guten Lösung ein zweiter Alarm für eine zufällig gewählte Zeit festgelegt. Wenn dieser zweite Alarm ausgelöst wird, ruft die Anwendung alle erforderlichen APIs auf und speichert die Ergebnisse. Wenn die Anzeige der Anwendung zu Beginn der Minute aktualisiert werden soll, verwendet sie zuvor gespeicherte Ergebnisse, anstatt die API noch einmal aufzurufen. Bei diesem Ansatz werden API-Aufrufe gleichmäßig über die Zeit verteilt. Außerdem verzögern die API-Aufrufe das Rendering nicht, wenn die Anzeige aktualisiert wird.

Abgesehen vom Beginn der Minute sollten andere häufige Synchronisierungszeiten, die Sie nicht als Ziel haben, der Beginn einer Stunde und der Beginn jedes Tages um Mitternacht sein.

Antworten verarbeiten

In diesem Abschnitt wird gezeigt, wie diese Werte dynamisch aus Webdienstanforderungen extrahiert werden können.

Die Google Maps-Webdienste bieten Antworten, die leicht verständlich, aber nicht wirklich nutzerfreundlich sind. Wenn Sie eine Abfrage ausführen, anstatt einen Datensatz anzuzeigen, möchten Sie wahrscheinlich einige spezifische Werte extrahieren. Im Allgemeinen sollten Sie Antworten aus dem Webdienst parsen und nur die Werte extrahieren, die Sie interessieren.

Welches Parsing-Schema Sie verwenden, hängt davon ab, ob Sie die Ausgabe in JSON zurückgeben. JSON-Antworten liegen bereits in Form von JavaScript-Objekten vor und können in JavaScript auf dem Client verarbeitet werden.