Olá! Sejam muito bem-vindos a este curso sobre Node.js, com foco em gRPC. Vamos começar de maneira sólida, pois, como diz o ditado, "bem começado é metade feito".
Primeiramente, vamos entender o histórico, explorando a origem do gRPC e do RPC, além de compreender o conceito por trás dessa tecnologia. Com os fundamentos bem explicados, passaremos para a implementação prática.
Vamos realizar diversas atividades, e alguns trechos de código foram preparados para dar um pouco de spoiler sobre o que está por vir. Iremos combinar gRPC com a API Rest, trabalhar com monorepo, utilizando o pnpm com vários projetos, pacotes e aplicativos, além de um pacote compartilhado.
Neste módulo, vamos trabalhar com um pacote compartilhado que exporta diversas funcionalidades comuns a todos os nossos microsserviços. Implementaremos um método baseado no gRPC para buscar dados, conhecido como NARI. Além disso, aprenderemos a registrar essas funcionalidades de maneira organizada utilizando o pacote compartilhado.
No final, abordaremos o conceito de transmissão de dados em tempo real. Vamos criar pedidos e, quando o status de um pedido for alterado, faremos a transmissão de um evento, permitindo que o status do pedido seja atualizado em tempo real.
Teremos a oportunidade de aprender como um serviço se conecta a outro e como podemos utilizar o Postman para receber essas mensagens.
Se já estivermos familiarizados com o NestJS, compreendendo seu funcionamento, e também com o Node.js, estaremos prontos para acompanhar este módulo.
Estamos animados para começar e esperamos que vocês também estejam. Prometemos que estaremos aqui para apoiar até que cheguemos ao próximo vídeo da primeira aula. Nos vemos lá!
Para compreendermos o GRPC, é necessário revisitar o passado e entender o que é o RPC. No início, quando os computadores começaram a se conectar em rede, cada máquina era isolada. As pessoas desenvolvedoras estavam acostumadas a fazer chamadas locais, escrevendo uma função e chamando-a com os parâmetros necessários para obter um resultado. O desafio era manter esse modelo mental, mas permitindo que a função fosse chamada através da rede, em vez de localmente. Esse era o cenário quando o RPC começou a surgir.
Naquela época, tínhamos a ARPANET, precursora da internet, e redes locais LAN. No entanto, não existia ainda a internet comercial, o HTTP, a web como conhecemos hoje, nem a computação em nuvem. As máquinas eram ilhas isoladas, sem conexão ou troca de dados. As funções existiam localmente, e o processo era simples: chamávamos uma função, passávamos parâmetros e armazenávamos o resultado.
A ideia do RPC era fazer uma chamada remota parecer uma chamada local. A pessoa desenvolvedora apenas codificava o resultado, recebendo, por exemplo, calculadora.soma(2, 3). O RPC cuidava de serializar os dados, transmiti-los pela rede, desserializá-los do outro lado, executar a função e retornar o resultado.
Se analisarmos uma linha do tempo, em 1976, começou-se a pensar em chamadas remotas. Em 1984, o SANA RPC popularizou o conceito. Em 1998, com o advento do XML e XMLRPC, tornou-se possível enviar headers no HTTP, permitindo trafegar dados além de HTML, como XML. O XMLRPC era basicamente RPC via HTTP, trafegando XML. No início dos anos 2000, surgiu o SOAP, que, apesar de ter um conceito bom, era complexo e burocrático de implementar. Somente em 2015, o Google abriu o que era conhecido como STUB, que se tornou o GRPC.
O GRPC é o foco do nosso curso. Ele funciona com um fluxo onde temos um código local que chama uma função local. Essa função, chamada de STUB, atua como um intermediário, cuidando de todo o processo de comunicação entre os computadores.
Ele vai serializar os parâmetros, enviar os dados, e a rede transmitirá essas informações. Quando chegam no STUB do outro lado, ele fará o inverso: desserializa os parâmetros, executa a função, retorna o resultado e, então, o processo se repete. Serializa a resposta, envia os dados, transmite, desserializa a resposta e o resultado chega de volta. É isso que queremos.
Qual é o papel do STUB? O cliente, nosso código, pensa, age e executa todas as ações da mesma forma que executamos uma função local. Porém, nos bastidores, ele está chamando esse "impostor", que realiza o trabalho de cuidar do transporte dos dados. Assim, o STUB é nosso representante local. Contudo, o RPC não elimina a complexidade, apenas a esconde. Estamos, metaforicamente, jogando a sujeira para debaixo do tapete. Ele não resolve o problema, apenas oculta a complexidade. Em vez de a pessoa desenvolvedora lidar com uma chamada remota, fazer isso via REST ou HTTP, o RPC cuida disso para nós. No entanto, a complexidade ainda existe, apenas foi abstraída.
Começaram a surgir as falácias da computação distribuída. Quais são essas falácias? Vamos lá. Primeiro, a rede é confiável? Não, a rede não é confiável, há muitas coisas que podem acontecer. A latência é zero? Também não. Muitos fatores influenciam a latência. A largura de banda é infinita? Não é infinita. A rede não é segura. A topologia vai mudar. Quem afirma que a topologia nunca muda está enganado. Existe um administrador? Nem sempre. O custo de transporte é zero? Também não é. E a rede é homogênea? Também não é. Estamos assumindo muitas premissas ao delegar isso para o RPC, mas na prática, a situação é bem diferente.
Isso nos leva aos problemas reais. Quais são esses problemas? Quando temos uma chamada local, ou ela funciona, ou dá erro. Utilizamos try e catch. Teremos uma resposta imediata, sem ambiguidade. Ou deu certo, ou não deu. Quando temos uma chamada remota, ela pode falhar no meio do caminho, pode demorar indefinidamente e nunca chegar à resposta. Podemos nos perguntar: será que chegou? Será que executou lá? Será que a resposta se perdeu no caminho? São muitos problemas que precisamos lidar ao fazer uma chamada remota.
E se o remoto parece local? Como saberemos se precisamos tratar timeout, retries, idempotência? Vamos abrir um parêntese para falar de idempotência, que é um termo que podemos usar para impressionar em um jantar de família. Idempotência, basicamente, é quando queremos realizar a mesma ação várias vezes e o resultado final deve ser sempre o mesmo. Se somamos 2 mais 2, esperamos que seja sempre 4. Se, nesse meio tempo, chamarmos 2 mais 2 e o resultado for diferente de 4, a operação não é idempotente. Ela não está gerando sempre o mesmo resultado quando os parâmetros são os mesmos.
Pode-se perguntar por que estamos falando de algo tão antigo. O RPC tem uma influência significativa nas tecnologias atuais, como o gRPC, que discutiremos durante o curso, o tRPC e o próprio GraphQL, que se baseiam em conceitos de chamada remota. Todas essas grandes ferramentas atuais descendem dessa ideia dos anos 1970. Os micro serviços geram muitas chamadas remotas, pois temos muitos serviços espalhados. Entender o RPC e o conceito de chamada remota é compreender o fundamento de tudo isso. É a base do que temos hoje em termos de chamada remota.
Para concluir este primeiro encontro, deixamos uma provocação sem resposta. Pense sobre isso: se o RPC tenta fazer o remoto parecer local, quais problemas surgem quando a rede falha? Quando a rede falha, o meio falha, e não é responsabilidade nem do cliente nem do servidor. Quais problemas isso cria? Reflita sobre isso. Se tiver dúvidas ou quiser discutir, participe do fórum.
Este primeiro assunto foi para estabelecer o cenário da época, por isso a referência ao DeLorean, do filme "De Volta para o Futuro". Se ainda não assistiu, recomendamos que veja. Fizemos essa viagem no tempo para entender o contexto da época. Sem compreender o conceito da época, é difícil entender o problema que estamos resolvendo e como estamos resolvendo.
O encontro de agora está encerrado. No próximo encontro, começaremos a falar diretamente sobre o gRPC. Já entendemos o que é o RPC e por que ele existe. Agora, vamos explorar o gRPC, entender o que ele é, como funciona e como se encaixa. Vamos fazer isso no próximo vídeo. Até mais.
Vamos dar sequência e falar sobre o GRPC. Qual era o cenário da época? No Google, havia milhões de requisições e um grande número de microserviços. Como fazer esses serviços conversarem de maneira escalável, com performance e fácil manutenção? Vamos viajar no tempo para entender isso. Nos anos 2000, já tínhamos um cenário com milhares de microserviços, dezenas de linguagens diferentes e 10 bilhões de requisições por segundo. O REST, sozinho, não conseguia atender a essa complexidade. Ele não foi pensado para algo desse nível.
Para resolver isso, surgiu o STUB, uma solução interna do Google. Era um sistema proprietário de IRPC, rápido e eficiente, mas preso à infraestrutura do próprio Google. Em 2015, o Google abriu o IRPC, tornando-o open source (código aberto), multilinguagem e pronto para produção. Já estava testado e maduro, pois funcionava internamente no Google há muito tempo.
O que é, afinal, o GRPC? Ele não é um protocolo, mas um framework de comunicação. Ele reuniu peças que já existiam na época, como o protocol buffers, que é responsável por serializar e deserializar dados, o HTTP2, que melhora a performance e comunicação dos dados, e a geração de código. O GRPC automatiza a criação de código a partir de definições de serviços. Esses são os três pilares do nosso framework de comunicação de IRPC.
Para ilustrar como o protocol buffers funciona, vamos ver um exemplo de definição de serviço. Aqui está um exemplo de um serviço chamado "Greeter", que possui uma chamada remota chamada SayHello:
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply);
}
Neste exemplo, o SayHello é uma chamada remota que recebe uma HelloRequest e retorna um HelloReply. Agora, vamos definir a mensagem HelloRequest:
message HelloRequest {
string name = 1;
}
O que é o protocol buffers? É um arquivo de definição com palavras reservadas como service, RPC e message. No exemplo acima, um HelloRequest é uma string com uma propriedade chamada name. O protocol buffers é binário, não trafega texto, o que o torna menor e mais rápido. Além disso, permite tipagem, pois estamos definindo o que recebemos e enviamos.
Por que destacamos o HTTP2? Antes, no HTTP1, tínhamos uma requisição por vez, headers repetidos e o streaming não existia no sentido literal. Com o HTTP2, passamos a ter mais requisições simultâneas, headers comprimidos e streaming bilateral, ou seja, na ida e na volta, de forma nativa. O HTTP1 não tinha especificação para isso, mas o HTTP2 sim, com suporte bidirecional.
O terceiro pilar é a geração de código. Temos um arquivo .proto e o proto C, nosso compilador, que gera código em TypeScript, Go, Python, Java, C#, Rust, PHP, entre outros. O proto C cuida disso para nós. O contrato se transforma em código, não apenas documentação, mas código compilado e tipado.
Se esquecermos de atualizar, o build pode falhar. O gRPC não se limita apenas ao conceito essencial de fazer uma requisição e esperar uma resposta; ele oferece muito mais. Vamos explorar as quatro formas de usar o gRPC.
Primeiro, temos o Unary. A ideia aqui é de unidade, de único. É o mais parecido com uma chamada HTTP normal: fazemos uma requisição e esperamos uma resposta. Nada além disso. Enviamos uma requisição e recebemos uma resposta.
Em seguida, temos o server streaming. Fazemos uma requisição e o servidor envia dados continuamente enquanto necessário. Enquanto houver dados para enviar, ele continuará transmitindo.
O oposto também existe: client streaming. Enviamos dados continuamente enquanto necessário. Quando terminamos, recebemos uma resposta. Por exemplo, ao enviar um arquivo muito grande, podemos fazer um stream desse upload. Quando terminamos de enviar todos os pedaços, o servidor processa e devolve uma resposta.
Também temos o bidirecional. Nesse caso, há transmissão de dados na ida e na volta, mantendo um canal aberto. Em situações como um chat, um jogo multiplayer ou qualquer tipo de colaboração em tempo real, temos esse conceito de stream bidirecional, com dados sendo enviados e recebidos continuamente.
No entanto, o gRPC não é uma solução universal. Antes de decidir usá-lo, é importante considerar alguns cenários onde ele pode não ser adequado. Por exemplo, se o cliente é um navegador, o suporte ainda é limitado, então pode não ser a melhor escolha. Se estamos oferecendo uma API pública para terceiros ou vendendo nossa API como um serviço, pode não ser ideal. O gRPC requer um debug fácil, mas trafega dados em formato binário, o que dificulta a compreensão do que está sendo transmitido. Com HTTP, conseguimos visualizar facilmente o que está sendo enviado e recebido.
Além disso, se não pudermos lidar com a curva de aprendizado, pode não ser o momento certo para adotar o gRPC. Estamos lidando com um modelo mental diferente, e talvez não tenhamos tempo para absorver isso agora.
O que faremos hoje? Vamos implementar isso na prática usando o Next.js. Vamos implementar o gRPC, os arquivos .proto e utilizar algumas abstrações do Next.js. O objetivo é focar nos conceitos, sem precisar implementar tudo do zero. O Next.js nos permitirá focar no gRPC, que é o que realmente importa.
Para implementar o gRPC no ambiente JavaScript, utilizamos algumas bibliotecas específicas. Aqui estão algumas delas:
@grpc/grpc-js - implementação JS
@grpc/proto-loader - carrega os .proto
@nestjs/microservices - abstração
Como o Next.js trata o gRPC? Ele atua como uma camada de transporte. A estrutura é a mesma que já conhecemos no Next.js: Controller, Service, Decorator, tudo igual. O que muda é o transporte subjacente.
Deixo uma questão para reflexão: se o gRPC exige um contrato rígido e compilado, como lidamos com mudanças na API sem quebrar os clientes antigos? Essa é uma preocupação específica, pois o gRPC é compilado. Como atualizamos isso mantendo a retrocompatibilidade com os clientes antigos? Pense sobre isso. Se quiser discutir, participe das comunidades da Alura, no Discord, ou no fórum.
Agora que temos os conceitos bem explicados e definidos, vamos partir para a implementação. Como fazemos na prática para implementar um cliente de RPC em um servidor de RPC e ver a mágica acontecer? Até a próxima!
O curso Node.js: serviços RPC escaláveis e transmissão de dados possui 151 minutos de vídeos, em um total de 43 atividades. Gostou? Conheça nossos outros cursos de Node.JS em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
2 anos de Alura
Matricule-se no plano PLUS 24 e garanta:
Jornada de estudos progressiva que te guia desde os fundamentos até a atuação prática. Você acompanha sua evolução, entende os próximos passos e se aprofunda nos conteúdos com quem é referência no mercado.
Programação, Data Science, Front-end, DevOps, Mobile, Inovação & Gestão, UX & Design, Inteligência Artificial
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você participa de eventos exclusivos, pode tirar dúvidas em estudos colaborativos e ainda conta com mentorias em grupo com especialistas de diversas áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
2 anos de Alura
Todos os benefícios do PLUS 24 e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Para estudantes ultra comprometidos atingirem seu objetivo mais rápido.
2 anos de Alura
Todos os benefícios do PRO 24 e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.
Conecte-se ao mercado com mentoria individual personalizada, vagas exclusivas e networking estratégico que impulsionam sua carreira tech para o próximo nível.