Usługi internetowe Google Maps Platform to zbiór interfejsów HTTP do usług Google, które dostarczają dane geograficzne dla aplikacji mapowych.
Ten przewodnik opisuje niektóre typowe praktyki przydatne podczas konfigurowania żądań usługi sieciowej i przetwarzania odpowiedzi usługi. Pełną dokumentację interfejsu API zarządzania mapami znajdziesz w przewodniku dla deweloperów.
Co to jest usługa internetowa?
Usługi sieciowe Google Maps Platform to interfejs do wysyłania żądań danych z interfejsu API Map Google do usług zewnętrznych i używania tych danych w aplikacjach Map. Zgodnie z ograniczeniami licencji w Warunkach korzystania z usługi Google Maps Platform te usługi są przeznaczone do używania w połączeniu z mapą.
Usługi internetowe interfejsów API Map Google używają żądań HTTP(S) do określonych adresów URL, przekazując parametry URL lub dane POST w formacie JSON jako argumenty do usług. Zwykle te usługi zwracają dane w treści odpowiedzi w formacie JSON, aby aplikacja mogła je przeanalizować lub przetworzyć.
Poniższy przykład pokazuje żądanie RESTGET do metody list Map
Configs:
https://mapmanagement.googleapis.com/v2beta/projects/PROJECT_NUMBER_OR_ID/mapConfigs
W treści żądania Authorization headerumieść prośbę o token OAuth.
Dostęp SSL/TLS
Protokół HTTPS jest wymagany w przypadku wszystkich żądań Google Maps Platform, które używają kluczy API lub zawierają dane użytkowników. Żądania wysyłane przez HTTP, które zawierają dane wrażliwe, mogą zostać odrzucone.
Tworzenie prawidłowego adresu URL
Może Ci się wydawać, że „prawidłowy” adres URL jest oczywisty, ale tak nie jest. Adres URL wpisany na przykład w pasku adresu w przeglądarce może zawierać znaki specjalne (np."上海+中國"). Przed przesłaniem przeglądarka musi wewnętrznie przetłumaczyć te znaki na inne kodowanie.
Podobnie każdy kod, który generuje lub akceptuje dane wejściowe w formacie UTF-8, może traktować adresy URL ze znakami UTF-8 jako „prawidłowe”, ale przed wysłaniem ich na serwer WWW musi przetłumaczyć te znaki.
Ten proces nazywa się
kodowaniem URL lub kodowaniem procentowym.
Znaki specjalne
Musimy przetłumaczyć znaki specjalne, ponieważ wszystkie adresy URL muszą być zgodne ze składnią określoną w specyfikacji Uniform Resource Identifier (URI). Oznacza to, że adresy URL muszą zawierać tylko specjalny podzbiór znaków ASCII: znane symbole alfanumeryczne i niektóre znaki zarezerwowane do użycia jako znaki kontrolne w adresach URL. W tej tabeli znajdziesz podsumowanie tych znaków:
| Ustaw | znaków | Użycie adresu URL |
|---|---|---|
| Znaki alfanumeryczne | 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 | ciągi tekstowe, użycie schematu (http), port (8080) itp. |
| Niezarezerwowane | - _ . ~ | Ciągi tekstowe |
| Zarezerwowane | ! * ' ( ) ; : @ & = + $ , / ? % # [ ] | znaki sterujące lub ciągi tekstowe, |
Podczas tworzenia prawidłowego adresu URL musisz zadbać o to, aby zawierał on tylko znaki podane w tabeli. Dostosowanie adresu URL do tego zestawu znaków zwykle powoduje 2 problemy: pominięcie i zamianę:
- Znaki, które chcesz obsługiwać, nie należą do powyższego zestawu. Na przykład znaki w językach obcych, takie jak
上海+中國, muszą być zakodowane przy użyciu powyższych znaków. Zgodnie z powszechną konwencją spacje (które są niedozwolone w adresach URL) są często reprezentowane za pomocą znaku plusa'+'. - Znaki z powyższego zestawu są znakami zarezerwowanymi, ale muszą być używane dosłownie.
Na przykład symbol
?jest używany w adresach URL do oznaczania początku ciągu zapytania. Jeśli chcesz użyć ciągu „? and the Mysterions”, musisz zakodować znak'?'.
Wszystkie znaki, które mają być zakodowane w formacie URL, są kodowane za pomocą znaku '%' i dwuznakowej wartości szesnastkowej odpowiadającej znakowi UTF-8. Na przykład znak
上海+中國 w kodowaniu UTF-8 będzie zakodowany w formacie adresu URL jako
%E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B. Ciąg znaków ? and the Mysterians zostanie zakodowany jako %3F+and+the+Mysterians lub %3F%20and%20the%20Mysterians.
Typowe znaki, które wymagają kodowania
Oto kilka często używanych znaków, które muszą być zakodowane:
| Niebezpieczny znak | Zakodowana wartość |
|---|---|
| Spacja | %20 |
| ” | %22 |
| < | %3C |
| > | %3E |
| # | %23 |
| % | %25 |
| | | %7C |
Konwertowanie adresu URL otrzymanego z danych wejściowych użytkownika bywa czasami trudne. Na przykład użytkownik może wpisać adres jako „5th&Main St.”. Zwykle adres URL należy tworzyć z jego części, traktując dane wejściowe użytkownika jako znaki dosłowne.
Dodatkowo adresy URL są ograniczone do 16384 znaków w przypadku wszystkich usług sieciowych Google Maps Platform i statycznych interfejsów API sieciowych. W przypadku większości usług ten limit znaków rzadko będzie osiągany. Pamiętaj jednak, że niektóre usługi mają kilka parametrów, które mogą powodować długie adresy URL.
Uprzejme korzystanie z interfejsów API Google
Źle zaprojektowane klienty interfejsu API mogą niepotrzebnie obciążać zarówno internet, jak i serwery Google. Ta sekcja zawiera sprawdzone metody dla klientów interfejsów API. Stosowanie się do tych sprawdzonych metod może pomóc Ci uniknąć zablokowania aplikacji z powodu niezamierzonego nadużywania interfejsów API.
Exponential Backoff
W rzadkich przypadkach podczas obsługi Twojego żądania może wystąpić błąd. Możesz otrzymać kod odpowiedzi HTTP 4XX lub 5XX albo połączenie TCP może po prostu ulec awarii gdzieś między Twoim klientem a serwerem Google. Często warto ponowić próbę, ponieważ kolejne żądanie może się powieść, mimo że pierwotne się nie udało. Nie należy jednak po prostu wielokrotnie wysyłać żądań do serwerów Google. Takie zapętlenie może przeciążyć sieć między klientem a Google, co spowoduje problemy dla wielu podmiotów.
Lepszym rozwiązaniem jest ponawianie próby z coraz większymi opóźnieniami między kolejnymi próbami. Zwykle opóźnienie jest zwiększane o czynnik mnożnikowy przy każdej próbie. Takie podejście jest znane jako wzrastający czas do ponowienia.
Rozważmy na przykład aplikację, która chce wysłać do interfejsu Time Zone API to żądanie:
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=1331161200&key=YOUR_API_KEYPoniższy przykład w Pythonie pokazuje, jak wysłać żądanie z wzrastającym czasem do ponowienia:
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}")
Uważaj też, aby w łańcuchu wywołań aplikacji nie było kodu ponawiania, który powoduje szybkie powtarzanie żądań.
Synchronizowane żądania
Duża liczba zsynchronizowanych żądań do interfejsów API Google może wyglądać jak atak typu DDoS na infrastrukturę Google i być odpowiednio traktowana. Aby tego uniknąć, zadbaj o to, aby żądania do interfejsu API nie były synchronizowane między klientami.
Rozważmy na przykład aplikację, która wyświetla czas w bieżącej strefie czasowej. Ta aplikacja prawdopodobnie ustawi alarm w systemie operacyjnym klienta, który będzie go budzić na początku minuty, aby można było zaktualizować wyświetlany czas. Aplikacja nie powinna wywoływać żadnych interfejsów API w ramach przetwarzania związanego z tym alarmem.
Wywoływanie interfejsu API w odpowiedzi na stały alarm jest niekorzystne, ponieważ powoduje synchronizację wywołań interfejsu API z początkiem minuty, nawet na różnych urządzeniach, zamiast równomiernego rozłożenia w czasie. Źle zaprojektowana aplikacja, która to robi, spowoduje na początku każdej minuty skok ruchu do 60-krotności normalnego poziomu.
Dobrym rozwiązaniem może być ustawienie drugiego alarmu na losowo wybraną godzinę. Gdy ten drugi alarm zostanie uruchomiony, aplikacja wywoła wszystkie potrzebne interfejsy API i zapisze wyniki. Gdy aplikacja chce zaktualizować wyświetlanie na początku minuty, używa wcześniej zapisanych wyników zamiast ponownie wywoływać interfejs API. Dzięki temu wywołania interfejsu API są rozłożone równomiernie w czasie. Ponadto wywołania interfejsu API nie opóźniają renderowania, gdy wyświetlacz jest aktualizowany.
Oprócz początku minuty należy uważać, aby nie kierować reklam na początek godziny i początek każdego dnia o północy.
Przetwarzanie odpowiedzi
W tej sekcji omawiamy, jak dynamicznie wyodrębniać te wartości z odpowiedzi usług internetowych.
Usługi internetowe Map Google zwracają odpowiedzi, które są łatwe do zrozumienia, ale nie do końca przyjazne dla użytkownika. Podczas wykonywania zapytania zamiast wyświetlać zestaw danych prawdopodobnie chcesz wyodrębnić kilka konkretnych wartości. Zazwyczaj warto przeanalizować odpowiedzi z usługi internetowej i wyodrębnić tylko te wartości, które Cię interesują.
Używany schemat analizowania zależy od tego, czy zwracasz dane wyjściowe w formacie JSON. Odpowiedzi w formacie JSON, które są już obiektami JavaScript, mogą być przetwarzane w JavaScript po stronie klienta.