Práticas recomendadas para usar os serviços da Web da API Geolocation

Os serviços da Web da Plataforma Google Maps são um conjunto de interfaces HTTP para serviços do Google que fornecem dados geográficos para seus apps de mapas.

Neste guia, descrevemos algumas práticas comuns úteis para configurar solicitações de serviço da Web e processar respostas de serviço. Consulte o Guia do desenvolvedor para ver a documentação completa da API Geolocation.

O que é um serviço Web?

Os serviços da Web da Plataforma Google Maps são uma interface para solicitar dados da API Maps de serviços externos e usar essas informações nos seus aplicativos. Esses serviços foram projetados para serem usados em conjunto com um mapa, de acordo com as restrições de licença nos Termos de Serviço da Plataforma Google Maps.

Os serviços Web das APIs Maps usam solicitações HTTP(S) para URLs específicos, transmitindo parâmetros de URL e/ou dados POST no formato JSON como argumentos para os serviços. Geralmente, esses serviços retornam dados no corpo da resposta como JSON para análise e/ou processamento pelo aplicativo.

Solicitações de geolocalização são enviadas usando POST para o seguinte URL:

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

Observação: todos os aplicativos da API Geolocation exigem autenticação. Saiba mais sobre as credenciais de autenticação.

Acesso SSL/TLS

O HTTPS é obrigatório para todas as solicitações da Plataforma Google Maps que usam chaves de API ou contêm dados do usuário. As solicitações feitas por HTTP que contêm dados confidenciais podem ser rejeitadas.

Uso adequado das Google APIs

Clientes de API mal projetados podem carregar mais carga do que o necessário na Internet e nos servidores do Google. Esta seção contém algumas das melhores práticas para cliente das APIs. Seguir essas práticas recomendadas pode ajudar a evitar que seu aplicativo seja bloqueado por abuso acidental das APIs.

Espera exponencial

Em casos raros, algo pode dar errado ao atender sua solicitação. Você pode receber um código de resposta HTTP 4XX ou 5XX, ou a conexão TCP pode simplesmente falhar em algum lugar entre seu cliente e o servidor do Google. Muitas vezes, vale a pena tentar reenviar a solicitação, já que a solicitação de acompanhamento pode ser bem-sucedida quando a original falha. No entanto, é importante não simplesmente tornar solicitações repetidas aos servidores do Google. Esse comportamento de loop pode sobrecarregar a rede entre o cliente e o Google, causando problemas para muitas partes.

Uma melhor abordagem é tentar novamente com intervalos maiores entre as tentativas. Normalmente, o atraso é aumentado por um fator multiplicativo a cada tentativa, uma abordagem conhecida como espera exponencial.

Por exemplo, considere um aplicativo que quer fazer esta solicitação à API Time Zone:

https://maps.googleapis.com/maps/api/timezone/json?location=39.6034810,-119.6822510&timestamp=1331161200&key=YOUR_API_KEY

O exemplo de Python a seguir mostra como fazer a solicitação com retirada exponencial:

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}")

Também é preciso tomar cuidado para que não haja um código de repetição mais acima na cadeia de chamadas do aplicativo que leve a solicitações repetidas em rápida sucessão.

Solicitações sincronizadas

Um grande número de solicitações sincronizadas para as APIs do Google pode parecer um ataque distribuído de negação de serviço (DDoS, na sigla em inglês) na infraestrutura do Google e ser tratado de acordo. Para evitar isso, verifique se as solicitações de API não estão sincronizadas entre os clientes.

Por exemplo, considere um aplicativo que exibe a hora do fuso horário atual. Este aplicativo provavelmente definirá um alarme no sistema operacional cliente despertando-o no início do minuto para que o horário exibido possa ser atualizado. O aplicativo não pode fazer chamadas de API como parte do processamento associado a esse alarme.

Fazer chamadas de API em resposta a um alarme fixo é ruim, porque resulta em chamadas de API sendo sincronizadas no início do minuto, mesmo entre dispositivos diferentes, em vez de serem distribuídas uniformemente ao longo do tempo. Um aplicativo mal projetado que faz isso produzirá um pico de tráfego sessenta vezes mais níveis normais no início de cada minuto.

Em vez disso, um bom possível design é ter um segundo alarme definido a um horário escolhido aleatoriamente. Quando esse segundo alarme é acionado, o app chama todas as APIs necessárias e armazena os resultados. Quando o aplicativo quer atualizar a tela no início do minuto, ele usa os resultados armazenados anteriormente em vez de chamar a API novamente. Com essa abordagem, as chamadas de API são distribuídas de maneira uniforme ao longo do tempo. Além disso, as chamadas de API não atrasam a renderização quando a tela está sendo atualizada.

Além do início do minuto, outros momentos de sincronização comuns com os quais você precisa tomar cuidado para não segmentar são no início de uma hora e de cada dia à meia-noite.

Processar respostas

Esta seção discute como extrair esses valores das respostas dos serviços web de forma dinâmica.

Os serviços da Web do Google Maps fornecem respostas fáceis de entender, mas não exatamente fáceis de usar. Ao realizar uma consulta, em vez de exibir um conjunto de dados, é recomendável extrair alguns valores específicos. Geralmente, você vai querer analisar as respostas do serviço da Web e extrair apenas os valores que são do seu interesse.

O esquema de análise usado depende do retorno da saída em JSON. As respostas JSON, já na forma de objetos JavaScript, podem ser processadas no próprio JavaScript no cliente.