Criando um microserviço em C# com banco de dados NoSQL (Parte II)

Rafael Dalsenter
4 min readJan 27, 2020

Dando continuidade ao artigo anterior, agora focaremos na contrução do Microserviço em .NET Core. Nele utilizaremos alguns conceitos de programação como injeção de dependência, repository e builder.

O Microserviço basicamente será uma API que retornará as informações de filmes inseridas no banco Cassandra, e também inserirá filmes novos. A princípio não há muitas validações no domínio, porém a estrutura estará pronta para estas serem adicionadas.

O código-fonte desse projeto pode ser localizado aqui

Construção do projeto

Inicialmente, estruturei a aplicação em algumas divisões de responsabilidade:

  • Domain: Aqui terá as classes de domínio com suas propriedades (por enquanto só existe o domínio NetflixTitle) e os Builders para construção dos domínios.
  • Application: Terá as classes de consulta ao banco (Repositories) e também as classes de inserção no banco (Services).
  • CrossCutting: Aqui terão as classes que podem ser utilizadas em qualquer camada, como objetos Dto, extensions e conexão com o Banco Cassandra.
  • Api: Api para exposição dos endpoints de Get e Post.
  • Tests: Projetos de testes unitários das camadas de Domain e Application.

Domínio

Aqui só teremos um domínio, que será o NetflixTitle, que basicamente representa o registro na base de dados. Na construção criei uma classe abstrata chamada BaseDomain que terá o método indicando se o domínio é valido e a lista de erros. Todos os domínios herdam dessa classe.

No domínio NetflixTitle somente teremos regras em dois campos que serão considerados “obrigatórios”. São Id e o Title. As propriedades são criadas como escrita privada, ficando restritas aos métodos com as regras:

Para construção do domínio, utilizei o pattern Builder (se você não conhece, tem esse artigo que detalha mais) criando a classe NetflixTitleBuilder.

Validando o domínio

Para garantir que as regras criadas no domínio estão corretas, podemos fazer através de testes unitários. Para isso, foi criado o projeto Domain.Tests. Nele é validado especialmente a criação de domínios com diferentes valores para as propriedades, assim confirmando se o resultado é o esperado. Abaixo tem um exemplo de um teste unitário que cria um domínio inválido, sem Title. Nesse caso, o meu resultado esperado é que o domínio seja inválido.

Application

A camada de Application contém as classes de consulta no banco de dados Cassandra (Repositories) e as classes de criação de novos registros (Services).

Repositories

Essas classes basicamente vão se conectar ao banco Cassandra, passar a CQLQuery e converter o objeto de retorno no Dto que eu especifiquei. A consulta montada até então recebe por parâmetro o “countryName” e retorna uma lista de títulos daquele país:

Services

A classe de service irá receber um Dto, montar um domínio a partir dele e inserir no banco de dados Cassandra (se domínio for válido):

Validando o Application

Para garantir as regras aplicadas, criei o projeto Application.Tests que irá testar as classes de leitura e escrita no banco de dados. Aqui serão testes unitários, portante utilizarei objetos Mock para “simular” retornos do banco de dados. Um exemplo do uso do Mock é o código abaixo, onde irei Mockar a classe CassandraContext, na qual, toda chamada do método InsertAsync que recebe qualquer objeto NetflixTitle e irá retornar como concluida com sucesso:

Aí para utilizar este Mock em um teste unitário fica simples:

CrossCutting

Aqui são as classes que podem ser utilizadas em qualquer camada (Cross). Objetos Dtos, Extensions e a conexão com o banco de dados Cassandra. Não há nada “diferente” por aqui.

Api

Aqui é o projeto “inicial” da aplicação. Nele eu exponho as rotas de Get e Post, e também inicializo a aplicação. Há algumas classes que geram algumas configurações:

  • IocStartup: Aqui eu configuro a injeção de dependência das classes do projeto.
  • MapperCassandraContext: Mapeamento do objeto de domínio nas chaves do banco Cassandra.
  • NetflixTitlesController: Controller principal com os métodos de Post e Get.

Para a API ficar mais intuitiva de consultar, foi utilizado o Swagger, que gera uma página HTML com todas as rotas de uma maneira bem elegante:

Os itens acima citados são chamados na classe Startup.

Aaaaa e não esquecendo, é claro, que também tem um Dockerfile gerado para subir a aplicação. Esse arquivo é gerado pelo próprio Visual Studio ao criar o projeto da Api e já deixa a mesma preparada para subir em contâiner.

O código-fonte desse projeto pode ser localizado aqui

Bom, aqui nesta segunda etapa detalhei como desenvolvi o projeto. No próximo artigo desta “série” irei configurar o ambiente AWS para subir esta aplicação :)

Até +

Originally published at https://rafaeldalsenter.github.io on January 27, 2020.

--

--

Rafael Dalsenter

Software Engineer. Enthusiastic about cloud services, containers, pipelines, etc. 😊