Olá! Seja bem-vindo ao curso de Arquiteto de Software da Alura. Meu nome é Felipe Cabrini.
Audiodescrição: Felipe é um homem branco, com cabelos pretos e olhos castanhos. Ele está vestindo uma camiseta preta.
Neste curso de Arquiteto de Software, abordaremos conteúdos mais avançados. Vamos explorar padrões de comunicações síncronas, como REST, GRPC e GraphQL. Também estudaremos padrões de comunicações assíncronas utilizando ferramentas como Kafka e RabbitMQ. Discutiremos tópicos sobre modelagem de ameaça e segurança, que são fundamentais na Arquitetura de Software.
Além disso, veremos como o Arquiteto de Software contribui para os pilares da observabilidade e como criar uma cultura de observabilidade nas equipes.
Iremos explorar alguns padrões avançados de Arquitetura de Software, como Event Sourcing (Fonte de Eventos) e Saga Pattern (Padrão Saga), entre outros. Se você é uma pessoa arquiteta de software e já trabalha na área, ou é uma pessoa desenvolvedora em Java que está aprendendo sobre Arquitetura de Software, este curso é ideal para se aprofundar nesses temas e explorar tópicos avançados de Arquitetura de Software.
Para extrair o máximo deste curso, sugerimos utilizar todos os recursos da Alura. Interaja bastante no fórum, poste suas dúvidas, faça comentários e tente ajudar outras pessoas. Procure realizar todas as atividades ao máximo possível. Isso certamente ajudará a fixar bem os conteúdos que abordaremos neste curso. Vamos lá?
Olá, sejam bem-vindos à aula de hoje. Vamos discutir sobre comunicação síncrona e assíncrona entre serviços e micro-serviços.
Para começarmos, vamos imaginar um cenário no qual fomos contratados como arquitetos de software. Temos um projeto em que a empresa realiza uma campanha de marketing agressiva, resultando em milhões de usuários acessando simultaneamente. O sistema possui uma página web onde os clientes preenchem um formulário e, ao final, enviam o cadastro. O objetivo é que os usuários recebam apenas uma mensagem de confirmação de que o cadastro foi efetuado com sucesso, aguardando um possível sorteio no futuro.
Nossa equipe de desenvolvimento criou uma página web com um micro-serviço que atende a essa página e envia os dados por meio de uma chamada REST HTTP para outro serviço de cadastro, que salva as informações no banco de dados. No entanto, durante o primeiro disparo da campanha, o sistema suportou apenas cinco minutos antes de cair, causando indisponibilidade e prejudicando a imagem da empresa. Mesmo após aumentar a memória, CPU e escalar os micro-serviços, o problema persistiu, especialmente no back-end de cadastro, que não suportava a quantidade de cadastros.
Fomos chamados para revisitar essa arquitetura e encontrar uma solução rápida, sem reescrever tudo, pois a empresa planejava outra campanha na semana seguinte. Precisamos garantir que o site permaneça estável e que os clientes consigam se cadastrar sem problemas, evitando desperdício de investimento em marketing.
Aqui está o desenho da arquitetura mencionada. Temos a campanha de marketing representada pelos clientes acessando o sistema front-end, que faz uma requisição HTTP para o back-end for front-end, e este, por sua vez, faz outra chamada para os serviços back-end que realizam o cadastro no banco de dados. O sistema verde é o que falha, e a falha ocorre na chamada HTTP.
A arquitetura é simples, mas não está conseguindo escalar para suportar milhões de requisições. Precisamos analisar o que deve ser entregue em tempo real para o usuário e o que pode ser entregue futuramente. Devemos questionar se o processamento precisa ser síncrono ou se pode ser assíncrono, enviando a requisição para uma fila ou tópico para processamento posterior. Mensagens síncronas são mais difíceis de escalar e impactam o cliente em caso de instabilidade. Já as assíncronas permitem que o consumidor processe na velocidade que consegue, sem acoplamento direto com o produtor.
Neste cenário, onde o usuário apenas recebe um feedback de cadastro efetuado, podemos transformar o processamento de síncrono para assíncrono. O usuário não precisa esperar o cadastro ser concluído imediatamente. Podemos enviar o evento para um tópico Kafka e devolver a mensagem de sucesso ao usuário, enquanto o back-end processa o evento posteriormente.
Com essa abordagem, o sistema nunca cairá, apenas poderá haver um atraso no cadastro. A experiência do usuário será sempre positiva, pois o front-end e o back-end azul permanecerão online. A campanha de marketing será um sucesso, pois todos conseguirão se cadastrar, e o evento será processado no Kafka em algum momento.
Vimos que existem dois tipos principais de comunicação nos sistemas: síncrona e assíncrona. Na comunicação síncrona, a execução é bloqueante, aguardando a resposta. Na assíncrona, é não bloqueante, permitindo que o evento seja processado futuramente. A comunicação síncrona requer que todos os sistemas estejam disponíveis simultaneamente, enquanto a assíncrona permite um acoplamento temporal mais flexível.
Os protocolos típicos de mensagens síncronas incluem HTTP REST, gRPC e GraphQL, enquanto para comunicação assíncrona temos MQTT, Kafka e JMS. Nem sempre é possível usar apenas um tipo de comunicação; devemos analisar os trade-offs e escolher a melhor abordagem para cada situação.
Em resumo, a comunicação síncrona pode apresentar problemas de latência e responsividade, enquanto a assíncrona oferece maior flexibilidade e escalabilidade. Devemos sempre considerar os benefícios e desafios de cada abordagem ao projetar a arquitetura de um sistema.
A comunicação síncrona proporciona uma resposta imediata à ação realizada com sucesso, mas pode aumentar a latência. Se o serviço apresentar algum gargalo ou lentidão, o usuário perceberá imediatamente. Por outro lado, a comunicação assíncrona melhora a responsividade do sistema, pois podemos postar no Kafka e o consumidor não precisa se preocupar com isso. Em termos de throughput (vazão) e escalabilidade, os sistemas assíncronos conseguem lidar com um volume muito maior de requisições em um curto espaço de tempo, processando de forma assíncrona. O processamento ocorre no consumidor em um segundo momento.
Entretanto, a comunicação assíncrona apresenta desafios relacionados à consistência dos dados. Na comunicação síncrona, como há sincronismo com as requisições, a consistência dos dados é imediata. Quando o usuário solicita um dado, ele é buscado no banco e está cadastrado. Assim, o estado do banco reflete a requisição do usuário. Por outro lado, em uma requisição assíncrona, se a mensagem não for consumida, o dado ainda não estará no banco, podendo resultar em uma consistência eventual, o que é mais difícil de gerenciar. Existem requisitos adicionais a serem trabalhados para garantir uma consistência forte em uma comunicação assíncrona.
Sistemas assíncronos são geralmente mais complexos. Implementar uma chamada REST, criar um cliente em um servidor e desenvolver uma API é mais simples. No entanto, ao lidar com mensagens assíncronas, é necessário envolver um terceiro sistema, como Kafka, Rabbit ou um sistema SaaS de mensageria, o que aumenta a complexidade. Isso implica em mais um fator a ser monitorado e acompanhado de perto, além de evoluir como plataforma.
Hoje, estamos comparando comunicação síncrona e assíncrona. Existem formas de mitigar os desafios, que abordaremos ao aprofundar na comunicação síncrona. Vamos discutir os padrões de comunicação, como o famoso request-response (requisição-resposta) e o publish-subscribe (publicar-assinar). Quando um serviço publica uma mensagem, outros consumidores se inscrevem nos tópicos e leem essa mensagem. Temos um produtor que faz a publicação e vários consumidores lendo a mensagem, conhecido como pub-sub.
Existem também padrões avançados de integração, como o message router (roteador de mensagens), que direciona uma mensagem com base em seu conteúdo. Um exemplo é quando precisamos enviar uma notificação push para o dispositivo móvel do usuário ou um e-mail. O produtor não precisa saber se deve enviar um e-mail ou push. Ele simplesmente envia a mensagem para o tópico, que decide se deve encaminhá-la para um sistema consumidor de e-mails ou de push, com base no conteúdo da mensagem.
Outro padrão é o splitter, que divide uma mensagem complexa em mensagens menores, distribuindo o processamento entre vários consumidores. Isso aumenta o paralelismo e é útil em cenários complexos. O oposto é o aggregator, que combina o resultado de várias mensagens em uma única. A mensageria agrupa as mensagens em uma só e envia para o consumidor.
Em ambos os casos, é importante tratar erros. Existem padrões como o circuit breaker, que simula um circuito eletrônico. Se o circuito estiver aberto, ele para de enviar a mensagem, permitindo que o serviço dependente se recupere. Os timeouts definem o tempo máximo de espera para uma requisição, evitando que o cliente seja sobrecarregado. O retry (retentativa) permite tentar novamente algumas chamadas, mas deve ser usado com cautela em transações financeiras para evitar duplicações. O fallback é uma alternativa quando um sistema falha, redirecionando para outro sistema.
Para concluir, a escolha entre comunicação síncrona e assíncrona deve ser baseada nas regras de negócios, considerando os trade-offs. A comunicação síncrona oferece simplicidade, mas com acoplamento forte. A mensageria assíncrona proporciona escalabilidade, mas é mais complexa. Adotar padrões de comunicação, como Publish-Subscribe e DLQ, é fundamental. Versionar APIs e esquemas de mensagens é importante, assim como estabelecer um padrão de observabilidade e monitoramento. Métricas básicas, como latência, throughput e taxa de erros, são essenciais para mensagens síncronas e assíncronas.
Ficamos por aqui. Obrigado. Até mais.
Olá! Sejam bem-vindos a mais uma aula. Hoje, vamos abordar REST, gRPC e GraphQL. Exploraremos as três tecnologias e suas diferenças. São tecnologias voltadas para comunicação síncrona. Já discutimos bastante sobre mensageria e agora vamos nos aprofundar mais em comunicação síncrona, diferenciando esses três padrões e quando utilizá-los em cada caso.
Antes de começarmos, vamos imaginar um cenário em que um time de desenvolvimento está em uma reunião. Nós somos chamados para essa reunião porque as pessoas desenvolvedoras não chegaram a um consenso sobre qual tecnologia síncrona devem usar. Uma pessoa desenvolvedora sênior sugere o uso de REST, enquanto outra, de nível pleno, viu em um evento que gRPC é a melhor opção. Por outro lado, outra pessoa desenvolvedora defende o uso de GraphQL, pois aprendeu em um curso que seria a melhor tecnologia. Precisamos decidir ou ajudar a chegar a um consenso sobre qual seria a melhor tecnologia. O que devemos responder? Claro que depende da situação. Quais perguntas devemos fazer para entender o contexto e decidir qual é a melhor tecnologia? Todas as três tecnologias, REST, gRPC e GraphQL, têm suas vantagens e desvantagens.
Vamos nos aprofundar nessas três tecnologias e técnicas, analisando suas vantagens, desvantagens e como mitigar essas desvantagens. REST é a mais utilizada, usando o protocolo HTTP, geralmente em conjunto com JSON, para chamadas principais e integrações entre front-end e back-end, mobile e back-end, e entre back-ends. Mais recentemente, surgiu o gRPC, voltado para comunicação entre back-ends, aproveitando o HTTP2. Por fim, temos o GraphQL, voltado para busca e leitura de dados de maneira dinâmica, com filtros dinâmicos.
Aqui temos um panorama das três camadas. Um desenho ilustra onde podemos usar cada tecnologia de maneira exemplificada e em alto nível. Temos clientes web e aplicativos que podem fazer chamadas GraphQL ou REST, e o back-end pode fazer chamadas REST ou gRPC entre si.
Quais são os fundamentos dos protocolos? REST é o mais simples e antigo, identificado por URLs, usando verbos HTTP como GET, POST, PUT, PATCH e DELETE. É stateless (sem estado), o que ajuda na escalabilidade, e se baseia no protocolo HTTP, aproveitando status de resposta, códigos de status e cabeçalhos para informações complementares. REST aceita JSON e XML, embora JSON seja mais comum atualmente.
O gRPC é uma tecnologia mais nova, criada para resolver problemas de comunicação entre micro-serviços, melhorando a performance. Utiliza comunicação binária com protocol buffers, em cima do HTTP2, eliminando o overhead da serialização. Possui um contrato forte com proto files, garantindo um contrato mais robusto que uma API JSON. Permite streaming unidirecional e bidirecional para comunicação em tempo real.
O GraphQL usa JSON e é semelhante ao REST, mas com um esquema voltado para buscas, permitindo flexibilidade maior. Aceita apenas JSON, enquanto o gRPC usa protocol buffers binários e o REST aceita JSON e XML. REST funciona em HTTP1 e HTTP2, gRPC apenas em HTTP2, e GraphQL em qualquer versão HTTP.
As definições de APIs e documentações variam: REST usa OpenAPI e Swagger, gRPC usa proto files, e GraphQL pode usar GraphiQL ou CodeGen. O streaming no REST é limitado, enquanto no gRPC é nativo e no GraphQL pode ser feito via subscriptions.
REST é mais simples, com cache nativo e ferramentas maduras. gRPC é mais performático, com contratos rígidos e streaming bidirecional. GraphQL oferece flexibilidade para clientes, com consultas dinâmicas semelhantes a SQL para APIs.
As desvantagens incluem múltiplas requisições no REST, complexidade no gRPC e no GraphQL, e dificuldades de caching. REST é indicado para APIs públicas, CRUDs simples e integrações. gRPC é recomendado para comunicação interna entre micro-serviços e IoT. GraphQL é ideal para front-ends com dados complexos e dashboards.
Comparando a performance, REST requer muitas requisições, aumentando o número de roundtrips. gRPC permite multiplexação de requisições no HTTP2, enquanto GraphQL consolida chamadas em uma única requisição. A serialização no REST é mais custosa, enquanto no gRPC é mais compacta e performática. No GraphQL, há menos chamadas, reduzindo o overhead de parsing.
Se estivermos utilizando HTTP2, conseguimos obter certos benefícios. Caso contrário, se estivermos em HTTP1, não teremos esses benefícios, mas podemos operar de maneira agnóstica em relação ao protocolo. Como podemos otimizar nosso payload? No caso do JSON e do REST, eles são mais verbosos, mas isso tem um lado positivo: é mais fácil de ler, depurar e é mais amigável para a pessoa desenvolvedora. Usar REST com JSON ou XML é mais amigável, pois permite ler facilmente os campos que estão sendo trafegados, bem como as requisições e respostas.
Podemos minimizar o tempo de parsing utilizando headers de compressão, como gzip ou Brotli, reduzindo o tamanho do JSON em 70% ou 80%. O gRPC, por outro lado, já é menor nativamente, mas utiliza arquivos binários, o que dificulta a visualização do que está sendo trafegado, tornando-o menos amigável para a pessoa desenvolvedora. Com GraphQL, o JSON é dinâmico, permitindo escolher os campos desejados. Se precisarmos de um campo, podemos selecionar apenas esse campo; se precisarmos de dez campos, podemos selecionar todos eles. O payload é dinâmico e podemos usar headers para minimizar e comprimir os dados. Se utilizarmos conscientemente apenas os campos necessários, o GraphQL será reduzido. No REST, ao enviar uma requisição, sempre recebemos todos os campos, independentemente de quantos utilizamos. No GraphQL, podemos selecionar apenas um ou dois campos de uma lista de dez, por exemplo.
O REST é escalável e cacheável, permitindo múltiplas requisições e facilitando a documentação de APIs públicas. O gRPC, embora não seja tão simples de usar, oferece a vantagem de permitir a abertura de um canal para múltiplas chamadas, aproveitando o HTTP2. O gRPC é indicado para comunicação entre back-ends. O GraphQL é útil quando precisamos fazer muitas consultas em uma única requisição, otimizando e evitando problemas de "n+1".
Para otimizar ainda mais nossas APIs REST, é recomendado usar um header de compressão, garantindo a redução da serialização e melhorando o desempenho. O gRPC já utiliza protocol buffers, otimizando os payloads. O problema "n+1" é comum em APIs REST, onde precisamos seguir padrões RESTful e criar APIs granulares para cada tipo de requisição. Isso pode resultar em múltiplas requisições para compor dados complexos, aumentando a latência e a sobrecarga de rede e servidor. No GraphQL, podemos consolidar consultas em uma única chamada, resolvendo o problema "n+1". No gRPC, minimizamos esse problema com uma conexão aberta e bidirecional, permitindo várias requisições dentro de uma chamada.
Para otimizar ainda mais nossas APIs, podemos usar query params, cache, paginação e filtragem de dados no REST. No gRPC, a comunicação bidirecional permite reutilização de conexões e compressão de dados nativa. No GraphQL, podemos usar data loaders e batch loading, limitar queries para prevenir ataques de DOS e usar queries pré-prontas para otimizar o desempenho.
Todas as nossas APIs, sejam REST, gRPC ou GraphQL, precisam de versionamento desde o início. No REST, o versionamento pode ser feito no header, na URL ou em query params. Adicionar novos campos é compatível, mas remover ou renomear campos resulta em uma quebra de versão. No gRPC, o protocol buffer possui regras claras de compatibilidade, e no GraphQL, a evolução contínua do schema permite adicionar campos sem quebra de versão. Campos depreciados podem ser indicados com a anotação @deprecated.
Em casos práticos, usamos REST para APIs públicas e integrações com parceiros, como Twitter, Stripe, PayPal e GitHub. Para comunicação entre micro-serviços, utilizamos gRPC, especialmente quando há necessidade de alta performance ou streaming de dados. O GraphQL é ideal para aplicações móveis, onde a eficiência de rede e a flexibilidade são essenciais.
REST, gRPC e GraphQL são tecnologias complementares, podendo ser usadas juntas em uma mesma arquitetura. REST é priorizado pela simplicidade e ecossistema maduro, gRPC para comunicação entre back-ends e streaming de dados, e GraphQL para flexibilidade em consultas complexas. Estudar e aprofundar-se nessas tecnologias e suas melhores práticas é essencial. Podemos usar as três tecnologias juntas, aproveitando seus benefícios e mitigando seus problemas.
Encerramos aqui. Obrigado e até a próxima!
O curso Padrões de Integração em Sistemas Distribuídos possui 296 minutos de vídeos, em um total de 33 atividades. Gostou? Conheça nossos outros cursos de Java 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.
Mobile, Programação, Front-end, DevOps, UX & Design, Marketing Digital, Data Science, Inovação & Gestão, 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.