Alura > Cursos de Programação > Cursos de .NET > Conteúdos de .NET > Primeiras aulas do curso Microsserviços e .NET6: implementando a comunicação

Microsserviços e .NET6: implementando a comunicação

Requisições síncronas - Apresentação

Boas-vindas ao curso de Microsserviços e .NET6: implementando a comunicação. Sou o Daniel e serei o seu instrutor ao longo deste curso de microsserviços com .NET na plataforma Alura.

O que vamos aprender? A proposta é trabalharmos com dois serviços: o ItemService, responsável por cadastrar itens para os restaurantes e o RestauranteService, responsável por mostrar os restaurantes.

Aprofundaremos as necessidades de cada serviço com o passar das aulas realizando algumas implementações. Mas um ponto de atenção é que não falaremos em como quebrar a aplicação em microsserviços a partir de um serviço. Partiremos de um projeto base e vamos suprir as necessidades desse projeto.

Aprenderemos como fazer a aplicação ser mais executável e entregável para outras plataformas. Toda a questão de conteinerização, vamos ver como conteinerizar as nossas aplicações de forma otimizada. Todas as partes de como lidar com comunicação síncrona e assíncrona também.

Caso tenha interesse, na plataforma Alura temos um curso de Microsserviços: padrões de projeto , é bem importante que você já possua esse conhecimento para conseguir acompanhar o conteúdo deste curso.

Vamos deixar uma lista de cursos de microsserviços e uma formação .NET que são pré-requisitos.

Cursos pré-requisitos:

Esses cursos e a formação são importantes, visto que são conhecimentos necessários que não abordaremos ao longo das aulas, vamos assumir que você já saiba esses conteúdos.

Vamos começar trabalhando com o projeto base, que disponibilizaremos para você, e seguir criando essas novas funcionalidades e entendendo como esses serviços vão se comunicar. No final, executaremos as aplicações para visualizarmos o funcionamento.

Essas são as informações iniciais que queria passar para você nesse vídeo, te espero no próximo vídeo para começarmos, até mais!

Requisições síncronas - Conhecendo o projeto

Começaremos com dois projetos-base com soluções já prontas. Neste curso não vamos focar em como construir uma API, como lidar com mapeamento de classes, entre outros conhecimentos prévios para realizar o nosso projeto. O que precisamos saber sobre os serviços que daremos continuidade?

Do lado direito do editor de código em "Gerenciador de Soluções" selecionaremos o serviço RestauranteService e, em seguida, "RestauranteController.cs". Este arquivo é o controlador, em que receberemos as requisições e, teremos um repositório que vai armazenar os dados em um banco de dados, entre outras funcionalidades de uma API.

Em "AppDbContext.cs" temos a parte de banco de dados, em "RestauranteCreateDto.cs" temos os DTOs que fazem o mapeamento ao salvar a requisição do usuário, em "Restaurante.cs" há os modelos, em "RestauranteProfile.cs" há o AutoMapper fazendo o mapeamento de um DTO para um modelo e vice-versa.

Esses conceitos foram aprendidos em cursos anteriores e estamos apenas colocando em prática. Na pasta ItemService temos o "ItemController.cs" em que teremos a parte de cadastramento de itens que o restaurante possui. Por exemplo, pegar os itens ou um item específico de um restaurante, pelo seu respectivo ID.

Toda essa lógica de acesso, de requisição, entre outras funcionalidades já estão implementadas. Com isso, falaremos sobre como esses dois serviços vão se comunicar.

Não nos preocuparemos também com a persistência. O nosso ItemService vai utilizar um banco de dados temporário enquanto o RestauranteService um banco de dados permanente usando o MySQL, em que persistem as informações. A única novidade é a questão referente à sintaxe que estamos utilizando do .NET 6.

Conseguimos observar que toda a parte de startup está dentro do Program.cs e usaremos ao longo do curso, no momento em que fizermos as requisições, o Swagger para visualizarmos de forma mais prática.

Logo, não temos nenhuma novidade neste projeto, não há nada que seja necessário destacarmos, já aprendemos esses conceitos. Iniciaremos com um conteúdo novo a partir dos próximos vídeos, em que vamos começar a desenvolver a comunicação entre esses dois serviços.

A primeira ideia que teremos no nosso desafio é: como podemos fazer o RestauranteService se comunicar com o ItemService? Isso aprenderemos no próximo vídeo, te espero lá!

Requisições síncronas - Enviando requisições http

Começaremos agora a desenvolver a comunicação entre o nosso RestauranteService e o ItemService, que de início vai ser bem simplória.

Vamos para o arquivo RestauranteController, em "RestauranteService > RestauranteController.cs". O que queremos fazer? Queremos que no momento em que efetuarmos o cadastro de um restaurante, através do CreateRestaurante, o ItemService receba esse registro para conseguirmos cadastrar novos itens nesse restaurante.

Para conseguirmos catalogar itens no restaurante, é preciso que o serviço de item receba o registro do restaurante.

Para conseguirmos fazer isso de forma efetiva, usaremos o método CreateRestaurante. Após salvarmos o restaurante no banco de dados em _repository.SaveChanges();, vamos efetuar a nossa requisição, depois de já termos o restauranteReadDto.

Como faremos essa requisição? A primeira solução é enviarmos essa requisição via HTTP. Para isso, vamos gerar uma classe que vai consistir em um método que vai ser responsável por fazer esse envio.

Criaremos um _itemServiceHttpClient. que vai ter o método EnviaRestauranteParaItemService() com o restauranteReadDto sendo enviado.

RestauranteController.cs

// código omitido 

 var restauranteReadDto = _mapper.Map<RestauranteReadDto>(restaurante);
  _itemServiceHttpClient.EnviaRestauranteParaItemService(restauranteReadDto);

Perceba que há um sublinhado em vermelho abaixo de _itemServiceHttpClient, isso significa que precisamos criá-lo. Para tal, com o mouse em cima selecionaremos "Alt + Enter" e escolheremos a opção "Gerar campo 'ItemServiceHttpClient'".

Subindo o código note que um private object _itemServiceHttpClient; foi gerado, no lugar de "object" vamos incluir "IItemServiceHttpClient", isto é, faremos a injeção de dependências através da interface.

Agora, vamos criar essa interface no arquivo RestauranteService, selecionando o botão direito do mouse em cima desse arquivo e escolhendo as opções "Adicionar > Nova Pasta" que chamaremos de "ItemServiceHttpClient".

Na pasta ItemServiceHttpClient criaremos a interface, selecionando as opções "Adicionar > Classe". No campo "Nome" na parte inferior da janela digitaremos "ItemServiceHttpClient" e clicaremos na opção "Interface" na parte central. Em seguida, pressionaremos o botão "Adicionar" no canto inferior direito.

Código inicial em ItemServiceHttpClient:

namespace RestauranteService.ItemServiceHttpClient
{
    public interface IItemServiceHttpClient
    {
    }
}

Vamos definir a assinatura do nosso método, public void EnviaRestauranteParaItemService() que vai receber RestauranteReadDto. Vai ser sugerido passar o "readDto": RestauranteReadDto readDto, depois selecionaremos "Alt + Enter" com o mouse em cima de "RestauranteReadDto readDto" para importar.

Ele vai recomendar fazermos com o namespace e na parte superior do código será incluído: using RestauranteService.Dtos;.

ItemServiceHttpClient

using RestauranteService.Dtos;

namespace RestauranteService.ItemServiceHttpClient
{
    public interface IItemServiceHttpClient
    {
        public void EnviaRestauranteParaItemService(RestauranteReadDto readDto);
    }
}

Agora, vamos gerar a classe que vai implementar essa interface, o "IItemServiceHttpClient". Dentro desta mesma pasta, clicaremos com o botão direito do mouse, escolheremos as opções "Adicionar > Classe" e no campo "Nome" digitaremos "ItemServiceHttpClient". Em seguida, vamos selecionar o botão "Adicionar" no canto inferior direito.

ItemServiceHttpClient

namespace RestauranteService.ItemServiceHttpClient
{
      public class ItemServiceHttpClient {

        }
}

Faremos com que essa classe implemente a nossa interface incluindo ": IItemServiceHttpClient".

// código omitido

namespace RestauranteService.ItemServiceHttpClient

Note que ItemServiceHttpClient possui um sublinhado em vermelho, isso significa que precisamos implementar. Novamente "Alt + Enter" e, em seguida, "Implementar a interface".

using RestauranteService.Dtos;

namespace RestauranteService.ItemServiceHttpClient
{
      public class ItemServiceHttpClient : IItemServiceHttpClient 
        {

            public void EnviaRestauranteParaItemService(RestauranteReadDto readDto)
        {
                     throw new NotImplementedException();
                }

        }
}

Por padrão, ele lança a exceção "throw new NotImplementedException();", visto que não estamos realizando comportamento nenhum. Mas queremos que o método EnviaRestauranteParaItemService envie uma requisição HTTP para o ItemService.

Para esse objetivo, no arquivo RestauranteController vamos importar o "IItemServiceHttpClient" no private. Agora não precisamos mais nos preocupar com este arquivo, toda parte já foi devidamente modificada.

Mas precisamos que, dentro do EnviaRestauranteParaItemService, ocorra o envio de uma requisição HTTP para o ItemService. Precisaremos efetivamente de um Client HTTP do próprio .NET para isso. Como utilizamos?

Voltando para o arquivo ItemServiceHttpClient criaremos um construtor e receberemos como parâmetro o HttpClient que chamaremos de "client". Selecionaremos "Alt + Enter" em cima de "client" e, em seguida, clicaremos na opção "Criar e atribuir o campo 'Client'".

ItemServiceHttpClient

// código omitido

    public class ItemServiceHttpClient : iItemServiceHttpClient
    {
            private readonly HttpClient client;

            public ItemServiceHttpClient(HttpClient client)
            {
                    this.client = client;
            }
    }
// código omitido

Repare que foi inserido tudo de forma automática, só vamos alterar o "this." para underline ("_") em "client” nas linhas 7 e 11, para manter o padrão.

// código omitido

    public class ItemServiceHttpClient : iItemServiceHttpClient
    {
            private readonly HttpClient _client;

            public ItemServiceHttpClient(HttpClient client)
            {
                    _client = client;
            }
    }
// código omitido

A partir disso, podemos fazer o envio da requisição através do client HTTP. Mas como isso funciona? Será que podemos diretamente, através do protocolo HTTP, enviar um objeto do C#? A resposta é não. Precisamos fazer outras operações com o objeto para que ele seja inviável via HTTP. Essa operação chamamos de serialização.

Para implementar a serialização, podemos remover a linha throw new NotImplementedException(); e inserir o conteúdo HTTP que queremos enviar, uma new StringContent(). Isto é, uma string que vai ser gerada a partir de parâmetros específicos.

//código omitido

public void EnviaRestauranteParaItemService(RestauranteReadDto readDto)
{
            var conteudoHttp = new StringContent 
                    (

                    )
}

O primeiro parâmetro que vamos passar é o conteúdo a ser enviado, o RestauranteReadDto. Mandaremos através de uma serialização: JsonSerializer.Serialize(readDto). Repare que vai aparecer um sublinhado em vermelho no "JsonSerializer", que teremos que importar selecionando "Alt + Enter > using System.Text.Json".

O segundo parâmetro é o enconding que utilizaremos, que no caso vai ser o UTF8. Em enconding selecionaremos "Alt + Enter > using System.Tex;". O último parâmetro é o media type, sendo o tipo de mídia que estamos enviando. No caso, é um JSON. Com isso, definimos o conteúdo HTTP que estamos enviando.

//código omitido

public void EnviaRestauranteParaItemService(RestauranteReadDto readDto)
{
            var conteudoHttp = new StringContent 
                    (
                      JsonSerializer.Serialize(readDto),
                        Encoding.UTF8,
                        "application/json"
                    );
}

Antes de enviar efetivamente, precisamos tornar o ItemServiceHttpClient um client HTTP de fato. Para isso, vamos no arquivo Program.cs e na linha 20, entre o AddScoped e o AddAutoMapper, criaremos um builder. Novamente vai aparecer informações com sublinhado em vermelho, então "Alt + Enter > using RestauranteService.ItemServiceHttpClient;".

Program.cs

builder.Services.AddHttpClient<IItemServiceHttpClient, ItemServiceHttpClient>();

Voltando para o controlador, basta fazermos a injeção no construtor. Para isso, selecionaremos "Alt + Enter > Adicionar parâmetros ao 'RestauranteController(IRestauranteRepository, IMapper)'" em private no nome do campo _itemServiceHttpClient, para adicionar o parâmetro no construtor.

Com isso, tudo vai funcionar conforme o esperado. Basta nos atentarmos agora a um detalhe que vamos aprender no próximo vídeo, sendo: para onde enviaremos a requisição? Sabemos que é para o ItemService, mas para qual controlador dentro dele? Como recebemos essa requisição?

Te espero no próximo vídeo para aprenderemos tudo isso.

Sobre o curso Microsserviços e .NET6: implementando a comunicação

O curso Microsserviços e .NET6: implementando a comunicação possui 143 minutos de vídeos, em um total de 48 atividades. Gostou? Conheça nossos outros cursos de .NET 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:

Aprenda .NET acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas