É importante entender como as APIs do Google funcionam com várias versões e implementações de HTTP se você estiver escrevendo um código personalizado que acessa a interface REST de uma API usando um cliente HTTP de terceiros. Para a maioria das cargas de trabalho, use as bibliotecas de cliente recomendadas do Google, que processam automaticamente a comunicação de servidor de baixo nível discutida neste documento.
Como trabalhar com protocolos de transferência (HTTP/*)
Esta seção descreve os protocolos de transferência com suporte (normalmente uma versão do HTTP) que as APIs do Google podem usar para se comunicar entre clientes e servidores, e como recomendamos que você os use.
Semântica do HTTP
Ao desenvolver o código de cliente da API, siga a semântica do protocolo HTTP padrão. Os proxies do lado do servidor ou as pilhas de API podem oferecer suporte apenas a um subconjunto de recursos HTTP padrão e também podem oferecer suporte às versões compatíveis com versões anteriores.
A semântica do protocolo HTTP que precisa ser processada pelas implementações de API do lado do servidor é controlada pela pilha do servidor. Confie nessa semântica apenas se esses recursos forem explicitamente documentados como parte da especificação da API, como o suporte ao armazenamento em cache.
Versões do HTTP
Os clientes podem usar qualquer protocolo HTTP/*, conforme permitido pela plataforma do cliente ou pela rede do lado do cliente, ou conforme negociado com o proxy do lado do servidor. Os protocolos com suporte incluem HTTP/1.1, HTTP/2 e HTTP/3 (QUIC). O suporte legado para HTTP/1.0 não é recomendado.
Alguns recursos da API podem ser compatíveis apenas com versões mais recentes de protocolos HTTP. Alguns são totalmente especificados apenas com HTTP/2 e HTTP/3, como o streaming multiplexado full-duplex. Esteja ciente das limitações de diferentes versões HTTP se você precisar de algum desses recursos como parte da especificação da API. Os recursos mais antigos, como o push de servidor HTTP/2, estão descontinuados e não são compatíveis com clientes da Web modernos.
Em geral, recomendamos HTTP/3 ou HTTP/2 para melhor desempenho, bloqueio de head-of-line reduzido e maior resiliência a falhas de rede.
Canais
Os canais se referem às conexões de rede da camada 4, que normalmente são soquetes TCP para HTTP/1.1 e HTTP/2, e soquetes UDP para HTTP/3 (QUIC). Os aplicativos clientes não devem fazer suposições sobre como os canais são gerenciados de ponta a ponta, já que as conexões são quase sempre encerradas pelos proxies do Google Front End (GFE) em nome do processo do servidor.
Clientes HTTP/1.1: se você estiver usando HTTP/1.1, sempre reutilize as conexões TCP (Connection: Keep-Alive). As bibliotecas de cliente HTTP normalmente gerenciam um pool de conexões para facilitar a reutilização. Evite o pipeline HTTP em conexões HTTP/1.1. Ele tem pouco suporte e pode causar problemas. Para mais informações, consulte HTTP e TCP.
Clientes HTTP/2 e HTTP/3: clientes e navegadores modernos usam predominantemente HTTP/2 ou HTTP/3. Os dois protocolos oferecem suporte à multiplexação, permitindo que várias solicitações e respostas estejam em trânsito simultaneamente em uma única conexão.
- HTTP/2: usa uma única conexão TCP por origem.
- HTTP/3: usa uma única conexão QUIC em UDP por origem. O QUIC integra criptografia TLS, controle de congestionamento e gerenciamento de conexão, geralmente oferecendo benefícios como configuração de conexão mais rápida (0-RTT ou 1-RTT) e imunidade ao bloqueio de head-of-line TCP em streams.
Com HTTP/2 e HTTP/3, os limites do navegador no número de conexões TCP paralelas a um único host (por exemplo, de 2 a 10) não são mais uma preocupação de desempenho principal. No entanto, os servidores (ou proxies como o GFE) ainda podem aplicar limites ao número máximo de streams simultâneos em uma única conexão HTTP/2 ou HTTP/3. Isso evita a sobrecarga e garante o uso justo de recursos (por exemplo, limitando solicitações simultâneas ou streams por conexão a 100).
HTTPS
Os clientes podem acessar uma API usando HTTPS ou HTTP, conforme compatibilidade da especificação da API. A negociação e as versões do TLS são transparentes para aplicativos clientes. Por padrão, as APIs do Google aceitam apenas tráfego HTTPS.
Formatos de solicitação e resposta
Esta seção descreve a estrutura das interações da API, incluindo o uso de dados codificados por URL, métodos HTTP específicos para ações RESTful e formatos de payload baseados em JSON.
Solicitar URLs
O mapeamento JSON-REST é compatível com dados de solicitação codificados de URL, e a solicitação HTTP e o corpo de resposta usam application/json como Content-Type.
O corpo HTTP usa uma matriz JSON para oferecer suporte a métodos RPC transmitidos, e a matriz JSON pode conter qualquer número de mensagens JSON ou uma mensagem JSON de status de erro.
URLs de solicitação longos
O URL tem uma limitação de comprimento prática, normalmente definida como 16 KB por padrão, embora isso possa variar dependendo do servidor. Se a API usar solicitações GET com URLs que excedam esse comprimento, as solicitações poderão não alcançar o servidor de API de destino e serão rejeitadas pelo Google Front End (GFE) com a mensagem de erro Your client has issued a malformed or illegal request.
Para ignorar a limitação, o código do cliente precisa usar uma solicitação POST com um Content-Type de application/x-www-form-urlencoded junto com o cabeçalho HTTP X-HTTP-Method-Override: GET. Essa abordagem também funciona para solicitações DELETE.
Métodos HTTP (verbos)
Se os URLs de solicitação seguirem o modelo REST, os métodos HTTP deles serão parte da especificação da API. Em particular, cada método de API precisa obedecer aos requisitos do protocolo HTTP com base no verbo HTTP específico ao qual o método de API é mapeado. Para mais informações, consulte a especificação do protocolo de transferência de hipertexto e o RFC do método PATCH.
Métodos seguros, como
HTTP GET e HEAD, não devem representar uma ação diferente da
recuperação. Especificamente, o GET do HTTP precisa ser considerado seguro e não pode ter nenhum efeito colateral visível para o cliente.
Idempotência em HTTP significa que os efeitos colaterais de várias solicitações idênticas são os mesmos de uma única solicitação. GET, PUT e DELETE são os métodos HTTP idempotentes relevantes para o guia de estilo. Observe que a idempotência é expressada apenas em termos de efeitos colaterais do servidor e não especifica nada sobre a resposta. Em particular, DELETE para recursos não existentes precisa retornar 404 (Not Found).
HTTP POST e PATCH não são seguros nem idempotentes (PATCH foi incluído no RFC 5789).
| Verbo HTTP | Seguro | Idempotente |
|---|---|---|
GET |
Sim | Sim |
PUT |
Sim | |
DELETE |
Sim | |
POST |
||
PATCH |
Formatos de payload
A solicitação e a resposta precisam compartilhar o mesmo Content-Type, exceto quando a solicitação é um
GETou umPOSTcom um corpo "application/x-www-form-urlencoded".JSON é compatível com o tipo MIME
application/json. O mapeamento de proto3 para JSON é especificado formalmente em Mapeamento do JSON.Os parâmetros de formulário (
POST) podem ser usados no lugar dos parâmetros de consulta de URL (GET), seguindo a mesma regra de mapeamento de estilo REST para mapear campos de solicitação para parâmetros de consulta. OContent-Typecompatível éapplication/x-www-form-urlencoded.
Streaming
Esta seção detalha como as APIs do Google processam o streaming de cliente e servidor, abordando especificamente as restrições de comunicação half-duplex em comparação com full-duplex e os requisitos de codificação para mensagens JSON transmitidas.
Half-duplex em comparação com full-duplex
O HTTP é um protocolo de solicitação-resposta que permite que o corpo de solicitação ou de resposta correspondente seja entregue em diferentes transportes orientados por stream, como TCP (HTTP/1.x) ou as variantes multiplexadas (SPDY, HTTP/2, QUIC).
Como desenvolvedor de clientes, seu aplicativo pode produzir o corpo da solicitação em um modo de streaming, ou seja, streaming de cliente. Da mesma forma, o aplicativo também pode consumir o corpo da resposta em um modo de streaming, ou seja, streaming de servidor.
No entanto, a especificação HTTP não especifica se um servidor pode transmitir o corpo da resposta (exceto para respostas de erro) quando o corpo da solicitação ainda está pendente. Essa semântica é conhecida como streaming full-duplex. Embora muitos programas de software de cliente/servidor/proxy HTTP permitam o streaming full-duplex, mesmo para HTTP/1.1, para evitar problemas de interoperabilidade, as APIs do Cloud baseadas em HTTP são restritas apenas ao streaming half-duplex.
Por padrão, os métodos de streaming de lances nas APIs do Cloud pressupõem a semântica full-duplex. Ou seja, não é seguro usar HTTP para invocar esse método. Se um método de streaming for somente half-duplex (conforme exigido pelo servidor), o documento da API precisará especificar claramente o comportamento half-duplex.
Para clientes de navegador, a semântica HTTP padrão é restringida pelas APIs de rede do navegador. Os navegadores oferecem suporte ao streaming de servidor (que geralmente respeita o enquadramento no nível de transporte) usando XHR ou Fetch. A API Fetch usa streams whatwg.
Devido às restrições do navegador, as APIs do Cloud que exigem suporte do navegador precisam evitar o streaming de cliente e o streaming full-duplex ou fornecer uma API separada especificamente para clientes de navegador.
De modo geral, o streaming de cliente pela Internet é menos útil do que o streaming de servidor. Isso ocorre porque o uso do streaming de cliente geralmente leva a um serviço com estado, o que afeta negativamente o balanceamento de carga e torna o sistema mais vulnerável a falhas ou ataques. O streaming de servidor, por outro lado, pode ser útil, já que pode reduzir significativamente a latência em redes com longos atrasos de RTT.
Codificação de mensagens
As mensagens JSON são codificadas como uma matriz no momento do streaming. O corpo de solicitação ou resposta permanecerá como um tipo JSON MIME válido.
Exemplo de codificação de streaming de cliente:
1 <length> <message-bytes> 1 <length> <message-bytes> … EOF
Exemplo de codificação de streaming de servidor:
1 <length> <message-bytes> … 2 <length> <status-bytes> EOF
Codificação no nível de transferência: a definição de StreamBody só é significativa na sua
alocação de IDs de tag para os campos "messages" e "status" <length> que
serão codificados com varint com 1 a 2 bytes para mensagens normais. Portanto, a sobrecarga total de codificação
é de 2 a 3 bytes por mensagem.
Um campo de preenchimento opcional é necessário para a compatibilidade com streams codificados por base64:
message StreamBody {
repeated bytes message = 1;
google.rpc.Status status = 2;
repeated bytes padding = 15; // max one-byte tag-id: xxx01111
}
As mensagens de erro precisam ser anexadas como o último elemento da matriz protobuf ou JSON, no mesmo formato que as mensagens normais.
Gerenciamento do estado
O comportamento semifechado é bem definido em qualquer versão do HTTP para um cliente ou servidor a fim de sinalizar para a outra extremidade que o corpo está completo.
Em particular, o código de cliente estará livre para completar a solicitação quando ainda estiver aguardando a resposta. Da mesma forma, um cliente pode ver uma resposta concluída quando o corpo da solicitação ainda está sendo gravado no servidor. O padrão HTTP espera que o cliente cancele ou complete a solicitação quando uma resposta for concluída de maneira inesperada, normalmente com um status de erro. Ou seja, em condições normais, o servidor não deve concluir uma resposta quando o cliente ainda estiver enviando a solicitação.
Cancelamento
A compatibilidade de cancelamento permite que um cliente anule uma solicitação quando ela ou a resposta ainda estiverem pendentes.
Não há suporte confiável para cancelamento de clientes HTTP/1.*, já que um cliente pode fechar uma conexão TCP após a conclusão da solicitação sem cancelar a transação de solicitação ou resposta. Um TCP FIN, no HTTP/1.1, não deve ser interpretado como um cancelamento, mesmo quando a conexão é marcada como keep-alive (Connection: Keep-Alive).
No entanto, depois que o cliente tiver fechado a conexão TCP, se o servidor tentar gravar qualquer dado para o cliente, um RST será gerado, o que pode acionar um cancelamento.
Observe que o cancelamento também é um problema para APIs que não são de streaming. Isso acontece principalmente quando a resposta envolve uma pesquisa longa e, portanto, a conexão pode ficar inativa por um período prolongado.
O cancelamento explícito é compatível com SPDY, HTTP/2 e QUIC, principalmente com a mensagem de go-away.
Keep-alive
A compatibilidade com keep-alive permite que um cliente ou servidor detecte um par com falha mesmo no caso de perda de pacotes ou falhas de rede.
Não há compatibilidade com keep-alive HTTP/1.1, já que o keep-alive do TCP não é uma abordagem viável.
O QUIC ou HTTP/2 oferece mensagens de controle especiais para implementar o suporte keep-alive por aplicativos, incluindo navegadores.
No entanto, a detecção confiável de keep-alive e falhas provavelmente exigirá uma biblioteca de cliente com o suporte necessário do lado do servidor: fazer streaming de longa duração pela Internet geralmente é propenso a erros ao confiar no HTTP básico como protocolo de comunicação.
Controle de fluxo
O suporte ao controle de fluxo exige que o cliente propague eventos de controle de fluxo no nível de transporte para o aplicativo cliente. O mecanismo real depende do estilo da API do cliente HTTP que seu aplicativo cliente usa. Por exemplo, você precisa de gravações e leituras de método de bloqueio ou leituras e gravações não bloqueadoras com suporte explícito ao controle de fluxo para que os aplicativos processem e respeitem eventos de controle de fluxo, a fim de evitar que o cliente ou o servidor fiquem sobrecarregados.
O HTTP/1.1 conta com o controle de fluxo TCP.
O SPDY e o HTTP/2 têm o próprio controle de fluxo no nível do stream, que também está sujeito ao controle de fluxo TCP no nível da conexão, já que as solicitações são multiplexadas em uma única conexão TCP.
O QUIC é executado no UDP e, portanto, gerencia o controle de fluxo completamente por conta própria.