Лучшие практики использования веб-служб API геолокации

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

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

Что такое веб-сервис?

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

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

Запросы геолокации отправляются с помощью POST на следующий URL-адрес:

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

Примечание . Все приложения API геолокации требуют аутентификации. Получите дополнительную информацию об учетных данных для аутентификации .

SSL/TLS-доступ

HTTPS требуется для всех запросов платформы Google Maps, которые используют ключи API или содержат пользовательские данные. Запросы, сделанные через HTTP и содержащие конфиденциальные данные, могут быть отклонены.

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

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

Экспоненциальный откат

В редких случаях при обслуживании вашего запроса что-то может пойти не так; вы можете получить код ответа HTTP 4XX или 5XX, или TCP-соединение может просто прерваться где-то между вашим клиентом и сервером Google. Часто имеет смысл повторить запрос, поскольку последующий запрос может быть успешным, если исходный запрос не удался. Однако важно не просто повторять повторные запросы к серверам Google. Такое зацикливание может перегрузить сеть между вашим клиентом и Google, что вызовет проблемы для многих сторон.

Лучший подход — повторить попытку с увеличением задержки между попытками. Обычно задержка увеличивается на мультипликативный коэффициент с каждой попыткой — подход, известный как экспоненциальная задержка .

Например, рассмотрим приложение, которое хочет отправить этот запрос к 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 в ответ на фиксированный сигнал тревоги — это плохо, поскольку в результате вызовы API синхронизируются с началом минуты, даже между разными устройствами, а не распределяются равномерно во времени. Плохо спроектированное приложение, делающее это, будет вызывать всплеск трафика, в шестьдесят раз превышающий нормальный уровень, в начале каждой минуты.

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

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

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

В этом разделе обсуждается, как динамически извлекать эти значения из ответов веб-службы.

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

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