Map Tiles API ウェブサービスを使用するベスト プラクティス

Google Maps Platform ウェブサービスは、地図アプリケーションに地理データを提供する Google サービスへの HTTP インターフェースのコレクションです。

このガイドでは、ウェブサービス リクエストの設定とサービス レスポンスの処理に役立つ一般的な方法について説明します。Map Tiles API の詳細なドキュメントについては、デベロッパー ガイドをご覧ください。

ウェブサービスとは

Google Maps Platform ウェブサービスは、外部サービスから Maps API データをリクエストし、そのデータを地図アプリケーション内で使用するためのインターフェースです。これらのサービスは、Google Maps Platform 利用規約のライセンス制限に従って、地図と組み合わせて使用するように設計されています。

Maps API ウェブサービスは、特定の URL への HTTP(S) リクエストを使用し、URL パラメータや 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 Maps Platform リクエストには、HTTPS が必要です。機密データを含む HTTP 経由のリクエストは拒否されることがあります。

Google API の適切な使用

API クライアントの設計が不十分な場合、インターネットと Google のサーバーの両方に必要以上の負荷がかかる可能性があります。このセクションでは、API のクライアントに関するベスト プラクティスについて説明します。これらのベスト プラクティスを参考にすると、API の不注意な不正使用によりアプリケーションがブロックされるのを回避できます。

指数バックオフ

まれに、リクエストの処理中にエラーが発生することがあります。4XX または 5XX の HTTP レスポンス コードが返されるか、クライアントと Google のサーバー間のどこかで TCP 接続が失敗することがあります。元のリクエストが失敗しても、フォローアップ リクエストが成功する可能性があるため、リクエストを再試行する価値はあります。ただし、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 の例は、指数バックオフを使用してリクエストを行う方法を示しています。

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 リクエストがクライアント間で同期されないようにする必要があります。

たとえば、現在のタイムゾーンの時刻を表示するアプリケーションについて考えてみましょう。このアプリケーションは、クライアント オペレーティング システムでアラームを設定し、1 分の開始時に起動して、表示される時刻を更新できるようにします。アプリは、そのアラームに関連する処理の一部として API 呼び出しを行ってはなりません。

固定アラームに応じて API 呼び出しを行うと、API 呼び出しが時間の経過とともに均等に分散されるのではなく、異なるデバイス間でも分の開始に同期されるため、適切ではありません。不適切に設計されたアプリケーションでは、毎分の開始時に通常の 60 倍のトラフィックの急増が発生します。

代わりに、2 つ目のアラームをランダムに選択した時刻に設定するという設計が考えられます。この 2 番目のアラームがトリガーされると、アプリは必要な API を呼び出して結果を保存します。アプリが 1 分の開始時に表示を更新する場合は、API を再度呼び出すのではなく、以前に保存した結果を使用します。この方法では、API 呼び出しが時間の経過とともに均等に分散されます。さらに、API 呼び出しによって、ディスプレイの更新時にレンダリングが遅れることはありません。

分の開始以外に、ターゲットにしないよう注意する必要がある一般的な同期時間は、時間の開始と、毎日の深夜 0 時の開始です。

レスポンスの処理

このセクションでは、これらの値をウェブサービス レスポンスから動的に抽出する方法について説明します。

Google マップ ウェブサービスは、わかりやすいレスポンスを提供しますが、ユーザー フレンドリーとは言えません。クエリを実行するときに、一連のデータを表示するのではなく、特定の値をいくつか抽出したい場合があります。通常は、ウェブサービスからのレスポンスを解析し、必要な値のみを抽出します。

使用する解析スキームは、JSON で出力を返すかどうかによって異なります。JSON レスポンスはすでに JavaScript オブジェクトの形式になっているため、クライアント上の JavaScript 自体で処理できます。