Práticas recomendadas para usar os serviços da web da API Pollen

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

Este guia descreve algumas práticas comuns úteis para configurar suas solicitações de serviço da Web e processar respostas de serviço. Consulte o guia do desenvolvedor para conferir a documentação completa da API Pollen.

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 os dados nos seus aplicativos do Maps. 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 da 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 seu aplicativo.

O exemplo a seguir mostra o URL de uma solicitação GET REST para o método forecast:lookup:

https://pollen.googleapis.com/v1/forecast:lookup?&key=API_KEY

Observação: todos os aplicativos da API Pollen 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 sensíveis podem ser rejeitadas.

Criar um URL válido

Você pode achar que um URL "válido" é imediatamente identificável, mas não funciona assim. Um URL inserido em uma barra de endereço de um navegador, por exemplo, pode conter caracteres especiais (por exemplo, "上海+中國"). O navegador precisa converter internamente esses caracteres em uma codificação diferente antes de transmiti-los. Da mesma forma, qualquer código que gere ou aceite entrada UTF-8 pode tratar URLs com caracteres UTF-8 como "válidos", mas também precisa converter esses caracteres antes de enviá-los a um servidor da Web. Esse processo é chamado de codificação de URL ou codificação por cento.

Caracteres especiais

É necessário converter caracteres especiais porque todos os URLs precisam estar em conformidade com a sintaxe especificada pela especificação do localizador uniforme de recursos (URI, na sigla em inglês). Efetivamente, isso significa que os URLs devem conter apenas um subconjunto especial de caracteres ASCII: os familiares símbolos alfanuméricos e alguns caracteres reservados para uso como caracteres de controle em URLs. Esta tabela resume esses caracteres:

Resumo de caracteres válidos para URLs
Conjuntode caracteresUso em URLs
Alfanuméricos 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 Strings de texto, uso do esquema (http), porta (8080) etc.
Não reservados - _ . ~ Strings de texto
Reservados ! * ' ( ) ; : @ & = + $ , / ? % # [ ] Caracteres de controle e/ou strings de texto

Ao criar um URL válido, você precisa garantir que ele contenha apenas os caracteres mostrados na tabela. Conformar um URL ao uso desse conjunto de caracteres geralmente causa dois problemas, um de omissão e um de substituição.

  • Caracteres que você quer processar existem fora desse conjunto. Por exemplo, os caracteres de idiomas estrangeiros como 上海+中國 precisam ser codificados como mostrado acima. Por convenção popular, os espaços (que não são permitidos nos URLs) também são geralmente representados pelo caractere do sinal de adição ('+').
  • Caracteres existem no conjunto acima como caracteres reservados, mas precisam ser usados literalmente. Por exemplo, ? é usado em URLs para indicar o início da string de consulta. Se você quiser usar a string "? and the Mysterions", codifique o caractere '?'.

Todos os caracteres que precisam ser codificados para serem adicionados a URLs são codificados por meio do uso de um '%' e um valor hexadecimal de dois caracteres correspondente ao seu caractere UTF-8. Por exemplo, 上海+中國 em UTF-8 seria codificado como %E4%B8%8A%E6%B5%B7%2B%E4%B8%AD%E5%9C%8B para uso em URLs. A string ? and the Mysterians seria codificada em um URL como %3F+and+the+Mysterians ou %3F%20and%20the%20Mysterians.

Caracteres comuns que precisam de codificação

Alguns caracteres comuns que precisam ser codificados:

Caractere inválido Valor codificado
Espaço %20
" %22
< %3C
> %3E
# %23
% %25
| %7C

Converter um URL recebido de uma entrada do usuário pode ser complicado. Por exemplo, um usuário pode inserir um endereço como "5th&Main St". Geralmente, você precisa criar o URL das partes dele, tratando quaisquer entradas do usuário como caracteres literais.

Além disso, os URLs estão limitados a 16.384 caracteres para todos os serviços da Web da Plataforma Google Maps e APIs estáticas da Web. Para a maioria dos serviços, esse limite raramente é atingido. No entanto, alguns serviços têm diversos parâmetros que podem resultar em URLs longos.

Uso adequado das Google APIs

Clientes de API mal projetados podem colocar 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 você a evitar que o aplicativo seja bloqueado por abuso inadvertido das APIs.

Retirada exponencial

Em casos raros, algo pode dar errado ao atender à 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 o cliente e o servidor do Google. Muitas vezes, vale a pena tentar a solicitação novamente, já que a solicitação de acompanhamento pode ser bem-sucedida quando a original falha. No entanto, é importante não simplesmente ficar em um loop repetido, fazendo solicitações para os servidores da Google. Esse comportamento de loop pode sobrecarregar a rede entre o cliente e o Google, causando problemas para várias partes.

Uma melhor abordagem é tentar novamente com intervalos maiores entre as tentativas. Geralmente, o intervalo é aumentado por um fator multiplicativo com 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 tentativa maior na cadeia de chamadas do aplicativo que leve a solicitações repetidas em uma rápida sucessão.

Solicitações sincronizadas

Grandes números de solicitações sincronizadas às APIs do Google podem parecer um ataque DDoS 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 do cliente, despertando-o no início do minuto para que a hora exibida possa ser atualizada. O aplicativo não deve fazer chamadas de API como parte do processamento associado a esse alarme.

Fazer chamadas de API em resposta a um alarme fixo é ruim, pois resulta em chamadas de API sendo sincronizadas com o início do minuto, mesmo entre diferentes dispositivos, em vez de serem distribuídos igualmente com o decorrer do tempo. Um aplicativo mal projetado fazendo isso vai produzir um pico de tráfego sessenta vezes maior do que o nível normal 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 aplicativo chama as APIs necessárias e armazena os resultados. Quando o aplicativo quer atualizar a tela no início do minuto, ele usa resultados armazenados anteriormente em vez de chamar a API novamente. Com essa abordagem, as chamadas de API são espalhadas igualmente 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 se deve tomar cuidado não escolher são os inícios de horas e de cada dia à meia-noite.

Como 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 amigáveis. Ao executar uma consulta, em vez de mostrar um conjunto de dados, é recomendável extrair alguns valores específicos. Geralmente, você deve analisar as respostas do serviço web e extrair somente os valores pertinentes.

O esquema de análise usado depende de você retornar a saída em JSON. As respostas JSON, que já estão na forma de objetos JavaScript, podem ser processadas no próprio JavaScript no cliente.