Comparar serviços gRPC com APIs HTTP

Por James Newton-King

Este artigo explica como os serviços gRPC se comparam às APIs HTTP com JSON (incluindo APIs Web do ASP.NET Core). A tecnologia usada para fornecer uma API para seu aplicativo é uma opção importante e o gRPC oferece benefícios exclusivos em comparação com as APIs HTTP. Este artigo discute os pontos fortes e fracos do gRPC e recomenda cenários para usar o gRPC em relação a outras tecnologias.

Comparação de alto nível

A tabela a seguir oferece uma comparação de alto nível de recursos entre gRPC e APIs HTTP com JSON.

Recurso gRPC APIs HTTP com JSON
Contrato Obrigatório (.proto) Opcional (OpenAPI)
Protocolo HTTP/2 HTTP
Carga útil Protobuf (pequeno, binário) JSON (grande, legível por humanos)
Prescrição Especificação estrita Flexível. Qualquer HTTP é válido.
Streaming Cliente, servidor, bidirecional Cliente, servidor
Suporte ao navegador Não (requer grpc-web) Sim
Segurança Transporte (TLS) Transporte (TLS)
Geração de código do cliente Sim OpenAPI + ferramentas de terceiros

Pontos fortes do gRPC

Desempenho

As mensagens do gRPC são serializadas usando o Protobuf, um formato de mensagem binário eficiente. O Protobuf serializa muito rapidamente no servidor e no cliente. A serialização do Protobuf resulta em cargas de mensagens pequenas, importantes em cenários limitados de largura de banda, como aplicativos móveis.

O gRPC foi projetado para HTTP/2, uma revisão importante do HTTP que fornece benefícios significativos de desempenho em relação ao HTTP 1.x:

  • Enquadramento binário e compactação. O protocolo HTTP/2 é compacto e eficiente tanto no envio quanto no recebimento.
  • Multiplexação de várias chamadas HTTP/2 em uma única conexão TCP. O multiplexação elimina o bloqueio de cabeçalho de linha.

HTTP/2 não é exclusivo do gRPC. Muitos tipos de solicitação, incluindo APIs HTTP com JSON, podem usar HTTP/2 e se beneficiar de suas melhorias de desempenho.

Geração de código

Todas as estruturas gRPC fornecem suporte de primeira classe para geração de código. Um arquivo principal para o desenvolvimento de gRPC é o .protoarquivo, que define o contrato de serviços e mensagens ddo gRPC. Nesse arquivo, as estruturas do gRPC geram uma classe base de serviço, mensagens e um cliente completo.

Ao compartilhar o arquivo .proto entre o servidor e o cliente, as mensagens e o código do cliente podem ser gerados de ponta a ponta. A geração de código do cliente elimina a duplicação de mensagens no cliente e no servidor e cria um cliente fortemente tipado para você. Não precisar escrever um cliente economiza tempo de desenvolvimento significativo em aplicativos com muitos serviços.

Especificação estrita

Uma especificação formal para a API HTTP com JSON não existe. Os desenvolvedores debatem o melhor formato de URLs, verbos HTTP e códigos de resposta.

A especificação do gRPC é prescritiva sobre o formato que um serviço gRPC deve seguir. O gRPC acaba com as discussões e economiza tempo para o desenvolvedor porque é consistente entre plataformas e implementações.

Streaming

O HTTP/2 fornece uma base para fluxos de comunicação em tempo real de longa duração. O gRPC fornece suporte de primeira classe para fluxo de dados por meio de HTTP/2.

Um serviço gRPC dá suporte a todas as combinações de fluxo de dados:

  • Unário (sem fluxo de dados)
  • Fluxo de dados de servidor para cliente
  • Fluxo de dados do cliente para o servidor.
  • Fluxo de dados bidirecional

Prazo/tempo limite e cancelamento

O gRPC permite que os clientes especifiquem quanto tempo estão dispostos a aguardar a conclusão de um RPC. O prazo é enviado ao servidor e o servidor pode decidir qual ação tomar se exceder o prazo. Por exemplo, o servidor pode cancelar solicitações de gRPC/HTTP/banco de dados em andamento quando tempo limite acabar.

Propagar o prazo e o cancelamento por meio de chamadas gRPC filho ajuda a impor limites de uso de recursos.

O gRPC é indicado para os seguintes cenários:

  • Microsserviços: o gRPC foi projetado para comunicação de baixa latência e alta taxa de transferência. O gRPC é ótimo para microsserviços leves em que a eficiência é crítica.
  • Comunicação ponto a ponto em tempo real: o gRPC tem excelente suporte para fluxo de dados bidirecional. Os serviços gRPC podem enviar mensagens por push em tempo real sem sondagem.
  • Ambientes poliglotas: as ferramentas do gRPC dão suporte a todas as linguagens de desenvolvimento populares, tornando o gRPC uma boa opção para ambientes de vários idiomas.
  • Ambientes restritos de rede: as mensagens do gRPC são serializadas com o Protobuf, um formato de mensagem leve. Uma mensagem gRPC é sempre menor que uma mensagem JSON equivalente.
  • Comunicação entre processos (IPC): transportes IPC, como soquetes de domínio Unix e pipes nomeados, podem ser usados com o gRPC para se comunicar entre aplicativos no mesmo computador. Para obter mais informações, confira comunicação entre processos com o gRPC.

Pontos fracos do gRPC

Suporte limitado a navegadores

Atualmente, não é possível chamar um serviço gRPC diretamente de um navegador. O gRPC usa pesadamente recursos de HTTP/2 e nenhum navegador fornece o nível de controle necessário em solicitações da Web para dar suporte a um cliente gRPC. Por exemplo, os navegadores não permitem que um chamador exija que o HTTP/2 seja usado ou forneça acesso a quadros HTTP/2 subjacentes.

O gRPC no ASP.NET Core oferece duas soluções compatíveis com o navegador:

  • O gRPC-Web permite que aplicativos de navegador chamem serviços gRPC com o cliente gRPC-Web e o Protobuf. O gRPC-Web requer que o aplicativo do navegador gere um cliente gRPC. O gRPC-Web permite que os aplicativos do navegador se beneficiem do alto desempenho e do baixo uso de rede do gRPC.

    O .NET tem suporte interno para gRPC-Web. Para obter mais informações, confira gRPC-Web em aplicativos gRPC do ASP.NET Core.

  • A transcodificação do gRPC JSON permite que os aplicativos de navegador chamem os serviços gRPC como se fossem APIs REST completas com JSON. O aplicativo do navegador não precisa gerar um cliente gRPC nem saber nada sobre gRPC. As APIs REST completas podem ser criadas automaticamente a partir de serviços gRPC anotando o arquivo .proto com metadados HTTP. A transcodificação permite que um aplicativo dê suporte a APIs Web gRPC e JSON sem duplicar o esforço de criação de serviços separados para ambos.

    O .NET tem suporte interno para criar APIs Web JSON de serviços gRPC. Para obter mais informações, consulte Transcodificação de gRPC JSON em aplicativos gRPC do ASP.NET Core.

Observação

A transcodificação do gRPC JSON requer a versão .NET 7 ou posterior.

Não legível por humanos

As solicitações da API HTTP são enviadas como texto e podem ser lidas e criadas por humanos.

As mensagens gRPC são codificadas com Protobuf por padrão. Embora o Protobuf seja eficiente para enviar e receber, seu formato binário não é legível por humanos. O Protobuf requer a descrição da interface da mensagem especificada no arquivo .proto para desserializar corretamente. Ferramentas adicionais são necessárias para analisar as cargas do Protobuf durante a transmissão e para compor solicitações manualmente.

Recursos como reflexão de servidor e a ferramenta de linha de comando gRPC existem para ajudar com mensagens Protobuf binárias. Além disso, as mensagens Protobuf dão suporte à conversão de e para JSON. A conversão interna do JSON fornece uma maneira eficiente de converter mensagens Protobuf de e para a forma legível por humanos ao depurar.

Cenários de estrutura alternativas

Outras estruturas são recomendadas em vez do gRPC nos seguintes cenários:

  • APIs acessíveis ao navegador: o gRPC não tem suporte total no navegador. O gRPC-Web pode oferecer suporte ao navegador, mas tem limitações e apresenta um proxy de servidor.
  • Transmissão de comunicação em tempo real: o gRPC dá suporte à comunicação em tempo real por meio de streaming, mas o conceito de transmitir uma mensagem para conexões registradas não existe. Por exemplo, em um cenário de sala de chat em que novas mensagens de chat devem ser enviadas para todos os clientes na sala de chat, cada chamada gRPC é necessária para transmitir individualmente novas mensagens de chat para o cliente. SignalR é uma estrutura útil para esse cenário. SignalR tem o conceito de conexões persistentes e suporte interno para transmitir mensagens.

Recursos adicionais