Back-End

17 out, 2018

Asp.Net Core 2.1 + Docker + NoSQL – Primeira aplicação NoSQL

Publicidade

Olá, meus queridos amigos!

Hoje venho mostrar pra vocês como criar uma aplicação NoSQL conteinerizada.

O que é NoSQL?

Você sabia que o conceito de NoSQL já tem mais de dez anos? Se não sabia, agora saiba que desde então foi descoberto que nem sempre banco de dados relacionais são capazes de resolver todos os problemas da melhor maneira. Dentre os diversos cenários complexos, imagine um simples cenário de alto volume de dados, como o Facebook.

Apenas falando de quantidade de usuários, existem, neste exato momento, 2.23 bilhões. Já pensou na quantidade de publicações? Aparentemente este é um cenário que um desenvolvedor não deveria se preocupar, mas infelizmente não funciona assim.

Entre os maiores problemas dos bancos relacionais, está o fato de que são otimizados para executar operações de escrita, e é por isso que existem várias formas normais e guias de boas práticas para manter a integridade dos dados. Porém, grande parte das aplicações atuais como e-commerces tem 90% das suas operações concentradas em operações de leitura, afinal, as pessoas mais navegam nas páginas de produtos do que os compram.

Saiba que utilizar as melhores práticas de bancos relacionais é uma coisa extraordinária se aplicada no cenário correto. Do contrário, você pode simplesmente quebrar sua aplicação, pois a complexidade para extração de dados é bem mais alta do que a de um banco não relacional, pois sempre requer a consulta de diversas tabelas para retornar um registro relativamente simples.

Um segundo cenário muito comum para utilização de banco de dados NoSQL é quando é necessário haver dinamicidade na estrutura dos dados. Em um banco de dados relacional quando você insere um determinado registro na tabela, ele contém colunas pré definidas, isso significa que o segundo registro, o terceiro, o quarto e todos os outros terão exatamente a mesma estrutura das colunas pré definidas. Em um banco de dados NoSQL, cada registro da collection pode ter uma estrutura completamente diferente da outra.

Como funciona na prática?

Veja um exemplo bem simples de como criar sua primeira aplicação utilizando bancos de dados não relacionais. Neste caso estou utilizando Mongo database para exemplificar.

Você pode conferir o código completo aqui.

Confira o código da classe ClientController para entender como funciona a manipulação de dados de um banco de dados NoSQL.

using System.Threading.Tasks;
using DockerNoSQL.WebAPI.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using MongoDB.Driver;

namespace DockerNoSQL.WebAPI.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class ClientController : ControllerBase
    {
        private readonly MongoClient _mongoClient;
        private readonly IMongoDatabase _mongoDatabase;
        public ClientController(IConfiguration configuration)
        {
            _mongoClient = new MongoClient(configuration.GetConnectionString("Development"));
            _mongoDatabase = _mongoClient.GetDatabase("Database");
        }

        [HttpGet]
        [Route("{id}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(500)]
        [ProducesResponseType(404)]
        public async Task<IActionResult> GetById([FromRoute] string id)
        {
            var collection = _mongoDatabase.GetCollection<PersonModel>("Person");
            var @object = await (await collection.FindAsync(filter => filter.Id == id)).FirstOrDefaultAsync();
            if (@object is null)
                return NotFound();
            return Ok(@object);
        }

        [HttpPost]
        [ProducesResponseType(201)]
        [ProducesResponseType(500)]
        [ProducesResponseType(404)]
        public async Task<IActionResult> Insert([FromBody]PersonModel personModel)
        {
            var collection = _mongoDatabase.GetCollection<PersonModel>("Person");
            await collection.InsertOneAsync(personModel);
            return CreatedAtAction(nameof(GetById), new { id = personModel.Id }, personModel);
        }
        
        [HttpDelete]
        [Route("{id}")]
        [ProducesResponseType(200)]
        [ProducesResponseType(500)]
        [ProducesResponseType(404)]
        public async Task<IActionResult> Remove([FromRoute] string id)
        {
            var collection = _mongoDatabase.GetCollection<PersonModel>("Person");
            var @object = await (await collection.FindAsync(filter => filter.Id == id)).FirstOrDefaultAsync();
            if (@object is null)
                return NotFound();
            await collection.DeleteOneAsync(filter => filter.Id == id);
            return Ok();
        }
    }
}

Confira também como é simples criar aplicações SQL conteinerizadas neste outro artigo. Veja também como se utiliza a imagem oficial do MongoDB no docker-compose file.

version: '3.3'

networks:
  dockernosql-network:
    driver: bridge

services:
  dockernosql.webapi:
    image: dockernosql.webapi
    build:
      context: /home/kenerry/workspace/DockerNoSQL/DockerNoSQL.WebAPI
      dockerfile: /Dockerfile
    networks:
      - dockernosql-network
    depends_on:
      - nosql.database

  nosql.database:
    image: mongo
    restart: always
    networks:
    - dockernosql-network

Por boas práticas, no arquivo docker-compose.yaml é indicado deixar somente as configurações básicas para que o arquivo fique legível, clean e não exponha à principio configurações desnecessárias. Configurações como variáveis de ambiente, portas, usuários e senhas, você tem a opção de deixar em um outro arquivo chamado docker-compose.override.yaml. Veja o exemplo:

version: '3.3'

services:
  dockernosql.webapi:
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
    ports:
      - 8080:80

  nosql.database:
    environment:
      ME_CONFIG_MONGODB_ADMINUSERNAME: root
      ME_CONFIG_MONGODB_ADMINPASSWORD: 123Aa321
    ports:
      - 27017:27017

Para rodar a aplicação, utilize: docker-compose build depois docker-compose up.

Por hoje é isso! Espero ter te ajudado. Deixe nos comentários se te ajudou! Muito obrigado pela leitura e até mais!

Quer saber mais sobre docker, docker compose, .net core, testes unitários e de integração? Baixe meu e-book free em https://kenerry.com.br.