ORM Sequelize no Node.js com Express.js
O ORM (Object-Relational Mapper), em português, Mapeamento Objeto-Relacional, é uma técnica utilizada para aproximar o paradigma POO (Programação Orientada a Objetos) ao paradigma de banco de dados relacional.
O uso dessa técnica de ORM é realizado através de um mapeador objeto-relacional que na maioria das vezes é uma biblioteca ou framework que ajuda no mapeamento e no uso do banco de dados.
Impedância de dados
Ao trabalharmos com aplicações orientadas a objetos que fazem uso de banco de dados relacionais para o armazenamento de informações, temos um problema que é conhecido como impedância objeto-relacional devido às diferenças que os dois paradigmas possuem.
Um banco de dados relacional trabalha com tabelas e relações entre elas para representar modelos da vida real. Dentro dessas tabelas, teremos várias colunas e a unidade que teremos para a representação no modelo relacional é uma linha, por exemplo:
Tabela: Produto
Já o paradigma orientado a objetos possui um modo diferente de trabalhar. Nele, nós temos elementos como classe, propriedades, visibilidade, herança e interfaces. Quando falamos de orientação a objetos não utilizamos tabelas e sim o objeto que representa algo do mundo real, seja ele abstrato ou concreto. Por exemplo:
Produto Objeto
ID: 1
Nome: Camisa
Valor: R$ 20,00
Descrição: Algodão
Agora, entendendo a diferença entre os dois, podemos entender as principais dificuldades que as diferenças entre os paradigmas causam, são elas:
- Representação dos dados e do modelo, tendo em vista que as estruturas são distintas;
- Modelo de integridade relacional do banco de dados relacional;
- Mapeamento entre os tipos de dados do banco de dados e da linguagem de programação.
Você deve estar se perguntando: "Beleza, mas como resolvo esse problema?".
Foi pensando nos problemas citados acima que surgiu o ORM, que define uma técnica para realizar a “comunicação” entre esses dois modelos. Uma das principais características é através do mapeamento das linhas para objeto.
As bibliotecas ou frameworks ORM definem o modo como os dados serão mapeados entre os ambientes, como eles serão acessados e gravados no bd, isso diminui muito o tempo levado para desenvolvimento, tendo em vista que não é necessário desenvolver toda essa parte.
Em um outro artigo trarei os vários padrões que existem no mercado para melhor entendimento. Neste artigo utilizaremos o Sequelize para demonstração.
O Sequelize é um ORM (Object-Relational Mapper) para Node.js, que tem suporte a vários banco de dados como MariaDB, MySQL, SQLite, PostgreSQL e como ORM ele serve para fazer o mapeamento de dados relacionais, como dito acima (tabelas, colunas e linhas) para objetos JS.
Iniciando o projeto
Antes de mais nada, precisaremos criar um projeto simples com Node.js, iniciarei criando uma pasta para começar o projeto na mesma. Irei executar os seguintes comandos:
Após a execução dos comandos acima, você terá criado uma pasta com um arquivo package.json dentro dela.
Com o projeto iniciado, vamos instalar algumas dependências necessárias:
Com as dependências instaladas, iremos criar um arquivo que será o nosso ponto de partida da aplicação, ele irá conter as configurações iniciais e a iniciação do servidor. Para isso, iremos criar um arquivo index.js na raiz do projeto com o seguinte conteúdo inserido nele:
Para testar o funcionamento do projeto, execute o comando node index.js. Em seguida, acesse o endereço http://localhost:3000, se tudo estiver funcionando corretamente, será retornada a mensagem Iniciado!. Se tudo estiver correto, poderemos passar ao próximo passo que é o de configurações do Sequelize.
Configurando o Sequelize no projeto
Antes de começarmos a configurar o Sequelize no projeto, devemos iniciá-lo, isso quer dizer que precisamos criar os arquivos de configuração, e para isso, basta executar o comando:
Após executarmos esse comando, deverão ser criados alguns arquivos no projeto, como as pastas config, migrations, models e seeders. Note que dá para visualizarmos que foram criados com sucesso após a execução do comando acima.
Nosso próximo passo será renomear o arquivo config/config.json para config/database.js e iremos alterar o seu conteúdo para:
Caso queira entender mais um pouco sobre as opções de configurações existentes, sugiro que você acesse a documentação do Sequelize, mas, de modo geral, essas configurações indicam um usuário e senha que você configurou no momento da instalação da sua máquina, além do nome da tabela que usaremos no projeto. Portanto, crie a tabela com o nome que desejar, para o nosso exemplo utilizei crud_sequelize.
Após as configurações acima terem sido concluídas, iremos criar duas novas pastas na raiz do projeto, a pasta database e a pasta app. Após a criação, mova os arquivos migrations e seeders para a pasta database e a pasta models para dentro de app, ficando com a estrutura assim:
Nosso próximo passo será configurar o Sequelize para encontrar os arquivos nas pastas que foram movidas. Para isso, na raiz do seu projeto, crie um arquivo chamado .sequelizerc e insira o seguinte conteúdo nele:
Caso queira entender mais sobre a estrutura do arquivo acima ou para que ele serve exatamente, sugiro que acesse a documentação do Sequelize.
Após o passo acima, o Sequelize já deve reconhecer corretamente os caminhos dos seus arquivos. Nosso próximo passo é configurarmos nossas models da aplicação, elas são a representação das tabelas do banco de dados em forma de classe, pois assim podemos manipulá-las mais facilmente através do nosso código.
Nosso primeiro passo será configurar o arquivo index.js que se encontra no caminho app/models/index.js será responsável por importar as models da aplicação. Seu código atualizado com as novas features do ES6 deve ficar assim:
Antes de iniciarmos e criarmos o nosso primeiro model, que será o model Usuário, iremos precisar fazer mais uma configuração, as migrations. Migrations são os arquivos que guardam as versões da base de dados, por exemplo, se você ou alguem que faz parte do seu time fizer alguma modificação na estrutura da tabela, a migration é a responsável por guardar essa mudança para que o time possa atualizar sua base de dados com ela.
Para podermos criar a nossa primeira migration, que será Usuário, executaremos o seguinte comando:
Quando o comando acima for executado, deverá ser criado em sua pasta migrations um arquivo, ao abri-lo, você verá uma estrutura de código com duas funções, a função up, que indica o que modificar no banco de dados quando executarmos a migration e a função down que funciona como um rollback, ou seja, a up faz, a down desfaz.
O arquivo de migration configurado para a nossa tabela de Usuários ficará assim:
Para testarmos o que fizemos até aqui, executamos o comando:
Note que ao executarmos o comando acima, um erro foi retornado, isso acontece pelo fato do Sequelize precisar de um pacote específico de banco de dados que definimos anteriormente no arquivo config/database.js, como usaremos o MySQL, iremos precisar do pacote mysql2, usando o comando a seguir teremos:
Após esse passo, execute novamente o comando db:migrate mostrado acima e tudo deve funcionar como esperado. Para verificar, abra o seu banco de dados e verifique se no banco de dados crud_sequelize foram criadas as tabelas SequelizeMeta e Users. A tabela SequelizeMeta que foi criada, guarda as informações sobre as migrations que já foram executadas, para que na próxima execução, caso não haja nenhuma alteração, o comando não precise ser executado. Apenas se houver algo novo, ele será executado, mas não será desde o começo.
Agora criaremos a model de Usuários.De início, criaremos um arquivo user.js dentro da pasta app/models e o arquivo irá conter o seguinte:
Agora que as configurações acabaram, falta apenas testar se a model está funcional, para isso vamos adicionar no arquivo index.js da raiz do projeto a importação para o arquivo app/models/index.js, ficando da seguinte forma:
const { User } = require(‘./app/models’).
E já que o arquivo é o arquivo index, podemos suprimi-lo da importação. Em seguida, iremos criar um usuário utilizando o comando da model disponibilizado pelo próprio Sequelize, ficando assim:
Se tudo der certo, quando executarmos o projeto com o comando node index.js, deverá ser criado um registro no banco de dados crud_sequelize na tabela Users.
Por fim, criaremos os métodos de CRUD diretamente nas rotas do arquivo index.js na raiz do projeto. Para criarmos as rotas usaremos:
Para finalizarmos, segue exemplo da seguinte situação: Caso quiséssemos criar uma função para registro de um novo usuário, ela ficaria assim:
As demais funções citadas acima, deixo para as práticas de vocês que estão fazendo a leitura do artigo.
Conclusão
Vimos que o Sequelize é um grande facilitador quando precisamos desenvolver aplicações, tendo em vista que tanto ele, quanto a maioria das ORM’s têm como objetivo permitir que o seu banco de dados seja mapeado em classes, abstraindo toda a lógica de manipulação de dados.
A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.