Веб-сервисы платформы Google Карт представляют собой набор HTTP-интерфейсов для сервисов Google, предоставляющих географические данные для ваших картографических приложений.
В этом руководстве описываются некоторые общие практики, полезные для настройки запросов веб-сервисов и обработки ответов сервисов. Обратитесь к руководству разработчика для полной документации по Roads API .
Что такое веб-сервис?
Веб-сервисы Google Maps Platform — это интерфейс для запроса данных Maps API из внешних сервисов и использования этих данных в ваших приложениях Maps. Эти сервисы предназначены для использования совместно с картой в соответствии с лицензионными ограничениями в Условиях обслуживания Google Maps Platform.
Веб-сервисы Maps API используют HTTP(S)-запросы к определенным URL-адресам, передавая параметры URL и/или данные POST в формате JSON в качестве аргументов сервисам. Обычно эти сервисы возвращают данные в теле ответа в виде JSON для анализа и/или обработки вашим приложением.
Типичный запрос веб-сервиса Roads API обычно имеет следующий вид:
https://roads.googleapis.com/v1/snapToRoads?parameters&key=YOUR_API_KEY
где snapToRoads
указывает на конкретную запрошенную услугу. Другие услуги Roads включают nearestRoads
и speedLimits
.
Примечание : Все приложения Roads API требуют аутентификации. Получите больше информации об учетных данных аутентификации .
SSL/TLS-доступ
HTTPS требуется для всех запросов Google Maps Platform, которые используют ключи API или содержат пользовательские данные. Запросы, сделанные по HTTP, которые содержат конфиденциальные данные, могут быть отклонены.
Создание действительного URL-адреса
Вы можете подумать, что "допустимый" URL-адрес очевиден, но это не совсем так. Например, URL-адрес, введенный в адресной строке браузера, может содержать специальные символы (например, "上海+中國"
); браузеру необходимо внутренне преобразовать эти символы в другую кодировку перед передачей. По той же причине любой код, который генерирует или принимает входные данные UTF-8, может рассматривать URL-адреса с символами UTF-8 как "допустимые", но также должен преобразовать эти символы перед отправкой их на веб-сервер. Этот процесс называется URL-кодированием или процентным кодированием .
Специальные символы
Нам необходимо перевести специальные символы, поскольку все URL-адреса должны соответствовать синтаксису, указанному в спецификации Uniform Resource Identifier (URI) . По сути, это означает, что URL-адреса должны содержать только специальный подмножество символов ASCII: знакомые буквенно-цифровые символы и некоторые зарезервированные символы для использования в качестве управляющих символов в URL-адресах. В этой таблице обобщены эти символы:
Набор | персонажи | Использование URL-адреса |
---|---|---|
Буквенно-цифровой | abcdefghijklm nopqrstuvwxyz ABCDEFGHIJKLM NOPQRSTUVWXYZ 0 1 2 3 4 5 6 7 8 9 | Текстовые строки, использование схемы ( http ), порт ( 8080 ) и т. д. |
Неограниченный | - _ . ~ | Текстовые строки |
Сдержанный | ! * ' ( ) ; : @ & = + $ , / ? % # [ ] | Управляющие символы и/или текстовые строки |
При создании допустимого URL-адреса необходимо убедиться, что он содержит только те символы, которые указаны в таблице. Приведение URL-адреса в соответствие с этим набором символов обычно приводит к двум проблемам: одна из них связана с пропуском, а другая — с заменой:
- Символы, которые вы хотите обработать, существуют за пределами указанного выше набора. Например, символы в иностранных языках, такие как
上海+中國
должны быть закодированы с использованием указанных выше символов. Согласно общепринятому соглашению, пробелы (которые не допускаются в URL) часто также представляются с использованием символа плюса'+'
. - Символы существуют в указанном выше наборе как зарезервированные символы, но должны использоваться буквально. Например,
?
используется в URL-адресах для обозначения начала строки запроса; если вы хотите использовать строку "? and the Mysterions", вам нужно будет закодировать символ'?'
.
Все символы, подлежащие URL-кодированию, кодируются с использованием символа '%'
и двухсимвольного шестнадцатеричного значения, соответствующего их символу UTF-8. Например,上海+中國
в UTF-8 будет URL-кодироваться как %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B
. Строка ? and the Mysterians
будут URL-кодироваться как %3F+and+the+Mysterians
или %3F%20and%20the%20Mysterians
.
Распространенные символы, требующие кодирования
Вот некоторые распространенные символы, которые необходимо кодировать:
Небезопасный персонаж | Закодированное значение |
---|---|
Космос | %20 |
" | %22 |
< | %3C |
> | %3E |
# | %23 |
% | %25 |
| | %7C |
Преобразование URL, который вы получаете из пользовательского ввода, иногда бывает сложным. Например, пользователь может ввести адрес как "5th&Main St." Как правило, вы должны составлять свой URL из его частей, рассматривая любой пользовательский ввод как буквальные символы.
Кроме того, URL-адреса ограничены 16384 символами для всех веб-сервисов Google Maps Platform и статических веб-API. Для большинства сервисов этот лимит символов будет редко достигаться. Однако следует отметить, что некоторые сервисы имеют несколько параметров, которые могут привести к длинным URL-адресам.
Вежливое использование API Google
Плохо спроектированные клиенты API могут нагружать больше, чем необходимо, как Интернет, так и серверы Google. В этом разделе приведены некоторые рекомендации для клиентов API. Соблюдение этих рекомендаций поможет вам избежать блокировки вашего приложения за непреднамеренное злоупотребление API.
Экспоненциальный откат
В редких случаях что-то может пойти не так при обслуживании вашего запроса; вы можете получить код ответа HTTP 4XX или 5XX, или соединение TCP может просто оборваться где-то между вашим клиентом и сервером Google. Часто стоит повторить запрос, так как последующий запрос может быть успешным, когда исходный не удался. Однако важно не просто зацикливаться, многократно отправляя запросы серверам Google. Такое зацикливание может перегрузить сеть между вашим клиентом и Google, вызывая проблемы для многих сторон.
Лучший подход — повторить попытку с увеличением задержки между попытками. Обычно задержка увеличивается на мультипликативный фактор с каждой попыткой, подход, известный как Exponential Backoff .
Например, рассмотрим приложение, которое хочет сделать следующий запрос к 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}")
Также следует следить за тем, чтобы выше в цепочке вызовов приложения не было кода повторных попыток, который приводит к повторным запросам в быстрой последовательности.
Синхронизированные запросы
Большое количество синхронизированных запросов к API Google может выглядеть как атака типа «распределенный отказ в обслуживании» (DDoS) на инфраструктуру Google и рассматриваться соответствующим образом. Чтобы избежать этого, следует убедиться, что запросы API не синхронизированы между клиентами.
Например, рассмотрим приложение, которое отображает время в текущем часовом поясе. Это приложение, вероятно, установит будильник в клиентской операционной системе, пробуждая ее в начале минуты, чтобы отображаемое время можно было обновить. Приложение не должно делать никаких вызовов API в рамках обработки, связанной с этим будильником.
Выполнение вызовов API в ответ на фиксированный сигнал тревоги плохо, поскольку это приводит к синхронизации вызовов API с началом минуты, даже между разными устройствами, а не к равномерному распределению во времени. Плохо спроектированное приложение, делающее это, создаст пик трафика в шестьдесят раз больше обычного в начале каждой минуты.
Вместо этого одним из возможных хороших решений является установка второго будильника на случайно выбранное время. Когда срабатывает этот второй будильник, приложение вызывает все необходимые ему API и сохраняет результаты. Когда приложение хочет обновить свой дисплей в начале минуты, оно использует ранее сохраненные результаты, а не вызывает API снова. При таком подходе вызовы API равномерно распределяются по времени. Кроме того, вызовы API не задерживают рендеринг при обновлении дисплея.
Помимо начала минуты, другие распространенные моменты синхронизации, на которые вам следует обратить внимание, — это начало часа и начало каждого дня в полночь.
Обработка ответов
В этом разделе обсуждается, как динамически извлекать эти значения из ответов веб-сервиса.
Веб-сервисы Google Maps предоставляют ответы, которые легко понять, но не совсем удобны для пользователя. При выполнении запроса, вместо отображения набора данных, вы, вероятно, захотите извлечь несколько конкретных значений. Как правило, вы захотите проанализировать ответы веб-сервиса и извлечь только те значения, которые вас интересуют.
Схема разбора, которую вы используете, зависит от того, возвращаете ли вы вывод в формате JSON. Ответы JSON, уже имеющие форму объектов Javascript, могут обрабатываться внутри самого Javascript на клиенте.