Рекомендации по использованию веб-сервисов Map Tiles API

Веб-сервисы платформы Google Карт – это набор HTTP-интерфейсов для сервисов Google, предоставляющих географические данные для картографических приложений.

В этом руководстве описаны некоторые распространенные методы, которые могут быть полезны при настройке запросов к веб-сервису и обработке ответов. Полная документация по Map Tiles API приведена в руководстве для разработчиков.

Что такое веб-служба?

Веб-сервисы платформы Google Карт – это интерфейс для запроса данных Maps API из внешних сервисов и использования этих данных в приложениях Карт. Эти сервисы предназначены для использования вместе с картой, как указано в Лицензионных ограничениях Условий использования платформы Google Карт.

Веб-сервисы Maps API используют HTTP(S)-запросы к определенным URL, передавая параметры URL и/или данные POST в формате JSON в качестве аргументов для сервисов. Как правило, эти сервисы возвращают данные в теле ответа в формате JSON для синтаксического анализа и/или обработки вашим приложением.

Пример запроса веб-сервиса – запрос метаданных Просмотра улиц, который имеет следующий вид:

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 и содержащие конфиденциальные данные, могут быть отклонены.

Бережное использование API Google

Плохо спроектированные API-клиенты могут создавать излишнюю нагрузку на интернет и серверы Google. В этом разделе описываются практические рекомендации для клиентов API. Следуя этим рекомендациям, вы сможете избежать блокировки приложения за непреднамеренное злоупотребление API.

Экспоненциальная выдержка

В редких случаях при обработке запроса может произойти ошибка. Вы можете получить код ответа HTTP 4XX или 5XX, или же TCP-подключение между вашим клиентом и сервером Google может просто не сработать. Часто имеет смысл повторить запрос, так как он может быть выполнен успешно. Однако не следует просто зацикливать запросы к серверам 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}")

Также убедитесь, что в цепочке вызовов приложения нет кода повторной попытки, который приводит к повторным запросам в быстрой последовательности.

Синхронизированные запросы

Большое количество синхронных запросов к API Google может выглядеть как распределенная атака типа "отказ в обслуживании" (DDoS) на инфраструктуру Google и обрабатываться соответствующим образом. Чтобы избежать этого, убедитесь, что запросы к API не синхронизируются между клиентами.

Например, рассмотрим приложение, которое показывает время в текущем часовом поясе. Вероятно, это приложение установит будильник в операционной системе клиента, который будет срабатывать в начале каждой минуты, чтобы обновлять отображаемое время. Приложение не должно выполнять вызовы API в рамках обработки, связанной с этим сигналом.

Вызовы API в ответ на фиксированный будильник нежелательны, поскольку они синхронизируются с началом минуты даже на разных устройствах, а не распределяются равномерно по времени. Плохо спроектированное приложение, которое делает это, будет вызывать всплеск трафика, в 60 раз превышающий нормальный уровень в начале каждой минуты.

Вместо этого, одним из хороших вариантов реализации будет будильник, устанавливаемый в случайно выбранную секунду. Когда срабатывает второй будильник, приложение вызывает необходимые API и сохраняет результаты. Когда приложение хочет обновить экран в начале минуты, оно использует ранее сохраненные результаты, а не вызывает API снова. При таком подходе вызовы API равномерно распределяются по времени. Кроме того, вызовы API не задерживают отрисовку при обновлении экрана.

Помимо начала минуты, не следует выбирать для синхронизации начало часа и начало дня (полночь).

Обработка ответов

В данном разделе описывается процесс динамического извлечения этих значений из ответов веб-служб.

Веб-сервисы Google Карт предоставляют ответы, которые легко понять, но не всегда удобно использовать. При выполнении запроса вместо отображения набора данных вы, вероятно, захотите извлечь несколько конкретных значений. Как правило, вам нужно будет проанализировать ответы веб-сервиса и извлечь только те значения, которые вас интересуют.

Схема синтаксического анализа зависит от того, возвращаются ли выходные данные в формате JSON. Ответы JSON, которые уже имеют форму объектов Javascript, могут обрабатываться в Javascript на стороне клиента.