Criando um microserviço em C# com banco de dados NoSQL (Parte II)
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.