Веб-сервисы платформы Google Карт – это набор HTTP-интерфейсов для сервисов Google, предоставляющих географические данные для картографических приложений.
В этом руководстве описаны некоторые распространенные методы, которые могут быть полезны при настройке запросов к веб-сервису и обработке ответов. Полная документация по Roads API приведена в руководстве для разработчиков.
Что такое веб-сервис?
Веб-сервисы платформы Google Карт – это интерфейс для запроса данных Maps API из внешних сервисов и использования этих данных в приложениях Карт. Эти сервисы предназначены для использования вместе с картой, как указано в разделе Лицензионные ограничения Условий использования платформы Google Карт.
Веб-сервисы 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 Карт, в которых используются ключи API или содержатся пользовательские данные. Запросы, отправленные по протоколу HTTP и содержащие конфиденциальные данные, могут быть отклонены.
Создание действительного URL
URL, введенный в адресную строку браузера, не всегда бывает действительным. Он может содержать специальные символы (например, "上海+中國"). Перед тем как выполнить переход по указанному адресу, браузер должен преобразовать эти символы в другую кодировку.
Аналогичным образом любой код, который создает или получает данные в формате UTF-8, может считать URL-адреса с символами UTF-8 действительными, но ему потребуется преобразовать эти символы, прежде чем отправлять их на веб-сервер.
Этот процесс называется кодированием URL или процентным кодированием.
Специальные символы
Необходимость преобразования символов связана с тем, что все URL должны соответствовать синтаксису, указанному в спецификации унифицированного идентификатора ресурсов (URI). На практике это значит, что URL должны содержать только определенный набор символов ASCII: стандартные буквенно-числовые символы и несколько зарезервированных символов, используемых в URL в качестве управляющих.
| Тип | Символы | Использование в URL-адресе |
|---|---|---|
| Буквенно-числовые | a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9 | Текстовые строки, схема (http), порт (8080) и т. д. |
| Незарезервированные | - _ . ~ | Текстовые строки |
| Зарезервированные | ! * ' ( ) ; : @ & = + $ , / ? % # [ ] | Управляющие символы или текстовые строки |
При создании действительного 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 |
Процентное кодирование текста, который вводит пользователь, может оказаться непростой задачей. Например, он может ввести адрес как "5th&Main St." Обычно URL необходимо создавать из отдельных частей, обрабатывая все вводимые пользователем данные как символьные литералы.
Кроме того, URL для всех веб-сервисов платформы Google Карт и Maps Static API могут содержать не более 16 384 символов. Для большинства служб этого размера более чем достаточно. но в некоторых случаях из-за ряда параметров длина URL может существенно увеличиться.
Бережное использование 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×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 в ответ на фиксированный будильник нежелательны, поскольку они синхронизируются с началом минуты даже на разных устройствах, а не распределяются равномерно по времени. Плохо спроектированное приложение, которое делает это, будет вызывать всплеск трафика, в 60 раз превышающий нормальный уровень в начале каждой минуты.
Вместо этого, одним из хороших вариантов реализации будет будильник, устанавливаемый в случайно выбранную секунду. Когда срабатывает второй будильник, приложение вызывает необходимые API и сохраняет результаты. Когда приложению нужно обновить данные на экране в начале минуты, оно использует ранее сохраненные результаты, а не вызывает API снова. В этом случае вызовы API будут распределены равномерно. Кроме того, вызовы API не задерживают отрисовку при обновлении экрана.
Помимо начала минуты, не следует выбирать для синхронизации начало часа и начало дня (полночь).
Обработка ответов
В этом разделе обсуждается динамическое извлечение значений из ответов веб-служб.
Веб-сервисы Google Карт предоставляют ответы, которые легко понять, но не очень удобно читать. При выполнении запроса вместо набора данных вам, вероятно, нужно извлечь несколько определенных значений. Как правило, вам нужно будет проанализировать ответы веб-сервиса и извлечь только те значения, которые вас интересуют.
Схема синтаксического анализа зависит от того, возвращаете ли вы выходные данные в формате JSON. Ответы в формате JSON, представляющие собой объекты JavaScript, можно обрабатывать в самом JavaScript на стороне клиента.