Google 地圖平台網路服務是一組 HTTP 介面,可連結 Google 服務,為地圖應用程式提供地理資料。
本指南說明一些常見做法,有助於設定網路服務要求及處理服務回應。如需 Map Tiles API 的完整說明文件,請參閱開發人員指南。
什麼是網路服務?
Google Maps Platform Web 服務提供介面,可向外部服務要求 Maps API 資料,並在 Maps 應用程式中使用。根據《Google 地圖平台服務條款》的授權限制,這些服務應與地圖搭配使用。
Maps API Web 服務會使用 HTTP(S) 要求,將網址參數和/或 JSON 格式的 POST 資料,當做引數傳遞至特定網址。一般來說,這些服務會在回應主體中以 JSON 格式傳回資料,供應用程式剖析和/或處理。
街景服務中繼資料要求就是一種網路服務要求,格式如下:https://tile.googleapis.com/v1/streetview/metadata?session=YOUR_SESSION_TOKEN &key=YOUR_API_KEY &panoId=panoId
注意:所有 Map Tiles API 應用程式都必須經過驗證。進一步瞭解驗證憑證。
SSL/TLS 存取權
凡是使用 API 金鑰或包含使用者資料的 Google 地圖平台要求,都必須透過 HTTPS 傳送。如果透過 HTTP 提出的要求含有機密資料,可能會遭到拒絕。
合理使用 Google API
設計不良的 API 用戶端可能會對網際網路和 Google 伺服器造成不必要的負載。本節提供一些 API 用戶端的最佳做法。遵循這些最佳做法,可避免應用程式因不慎濫用 API 而遭到封鎖。
指數輪詢
在極少數情況下,系統可能無法處理您的要求,您可能會收到 4XX 或 5XX HTTP 回應代碼,或 TCP 連線可能在用戶端和 Google 伺服器之間的某個位置失敗。通常值得重新嘗試要求,因為後續要求可能會在原始要求失敗時成功。不過,請勿只是重複向 Google 伺服器發出要求。這種循環行為可能會導致用戶端與 Google 之間的網路超載,造成多方問題。
較好的做法是重試,並在每次重試之間增加延遲時間。通常每次嘗試時,延遲時間都會增加一個乘數,這種方法稱為指數輪詢。
舉例來說,假設應用程式想向 Time Zone API 提出以下要求:
https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510×tamp=1331161200&key=YOUR_API_KEY以下 Python 範例說明如何使用指數輪詢提出要求:
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}")
此外,請務必確認應用程式呼叫鏈中沒有較高的重試程式碼,以免在短時間內連續傳送重複要求。
同步要求
如果同時向 Google API 發出大量同步要求,可能會被視為對 Google 基礎架構發動分散式阻斷服務 (DDoS) 攻擊,並受到相應處置。為避免這種情況,請確保 API 要求不會在用戶端之間同步處理。
舉例來說,假設某個應用程式會顯示目前時區的時間。這個應用程式可能會在用戶端作業系統中設定鬧鐘,在每分鐘開始時喚醒作業系統,以便更新顯示的時間。應用程式不應發出任何 API 呼叫,做為與該鬧鐘相關聯的處理作業。
在回應固定鬧鐘時發出 API 呼叫並非理想做法,因為這會導致 API 呼叫同步至分鐘的開頭,甚至在不同裝置之間也是如此,而不是隨著時間平均分配。如果應用程式設計不佳,就會在每分鐘開始時產生高達正常水準六十倍的流量。
相反地,一個可能的好設計是將第二個鬧鐘設定為隨機選擇的時間。當第二個鬧鐘響起時,應用程式會呼叫所需的任何 API 並儲存結果。當應用程式想在每分鐘開始時更新顯示內容,就會使用先前儲存的結果,而不是再次呼叫 API。這樣一來,API 呼叫就會平均分散在一段時間內。此外,更新螢幕時,API 呼叫不會延遲算繪。
除了每分鐘開始時,其他應避免同步處理的常見時間包括每小時開始時,以及每天午夜開始時。
處理回應
本章節討論如何從網路服務回應中,以動態方式擷取這些值。
Google 地圖網路服務提供的回應容易理解,但對使用者來說不夠友善。執行查詢時,您可能想擷取幾個特定值,而不是顯示一組資料。一般來說,您會想要剖析網路服務的回應,並只擷取您感興趣的值。
剖析配置取決於是否以 JSON 格式傳回輸出內容。JSON 回應本身就是 JavaScript 物件,因此可在用戶端上直接透過 JavaScript 處理。