Configurando o ORM Sequelize no NodeJS com ExpressJS

Node.js 14 de Jun de 2018

O Sequelize é um ORM (Object-Relational Mapper) para Node.js, que tem suporte aos bancos de dados PostgreSQL, MariaDB, MySQL, SQLite e MSSQL, como ORM ele faz o mapeamento de dados relacionais (tabelas, colunas e linhas) para objetos Javascript.

NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

Ele permite criar, buscar, alterar e remover dados do banco de dados utilizando métodos JS, além de permitir a modificação da estrutura das tabelas, com isso temos muita facilidade tanto na criação, população e migração de banco de dados.

Iniciando o projeto

Para começar iremos criar um projeto simples com o Node.js, vou criar uma pasta e em seguida iniciar o projeto nela executando:

mkdir NodeSequelize
cd NodeSequelize
npm init -y

Com isso você terá uma pasta criada com um arquivo package.json dentro dela, com o projeto iniciado vamos a instalação de algumas dependências.

Primeiro temos que ter instalado algum banco de dados para usar com o Sequelize, nesse exemplo vamos usar o MariaDB, que é a versão Open Source do MySQL, você pode encontrar mais detalhes sobre o download e a instalação dele nesse link.

Com o banco de dados instalado, vamos à instalação do Sequelize no projeto, e junto com ele vamos instalar também o sequelize-cli como dependência de desenvolvimento, o Express como framework Node.js e o Body Parser como middleware para as requisições, para isso basta executar o comando:

npm install sequelize express
npm install -D sequelize-cli
// ou
// yarn add sequelize express
// yarn add -D sequelize-cli

Com as dependências instaladas vamos criar um arquivo que será o ponto de entrada da aplicação, onde terão as configurações iniciais e a iniciação do servidor, para isso crie um arquivo index.js na raiz do projeto e insira o seguinte conteúdo nele:

NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.
const express = require('express');

const app = express();

app.use(express.urlencoded({ extended: false }));

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(3000);

Para testar o projeto basta salvar tudo e executar no terminal o comando:

node index.js

No navegador acesse o endereço http://localhost:3000, uma tela com a mensagem Hello World! deve ser retornada. Se funcionou corretamente podemos ir às configurações do Sequelize.

Você pode encontrar a estrutura inicial do projeto nesse link.

NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

Configurando o Sequelize no projeto

Antes de começar a configurar o Sequelize no projeto devemos iniciá-lo, ou seja, criar os arquivos iniciais de configuração, e para isso basta executar o comando:

./node_modules/.bin/sequelize init
// ou
// npx sequelize init

Esse processo deve criar alguns arquivos no projeto, como a pasta config, migrations, models e seeders.

A primeira coisa que vamos fazer é renomear o arquivo config/config.json para config/database.js e alterar seu conteúdo para:

module.exports = {
  username: 'root',
  password: 'root',
  database: 'crud_sequelize',
  host: '127.0.0.1',
  dialect: 'mysql',
}

Para ler mais sobre as opções de configuração veja esse link, mas basicamente essas são as configurações que indicam qual o usuário e senha que você configurou no momento da instalação na sua máquina além do nome da tabela que vamos usar nesse projeto, portanto crie uma tabela no seu banco de dados com o nome que desejar, no meu caso estou usando crud_sequelize.

/!\ DICA /!\: Para facilitar a manipulação de banco de dados você pode usar um cliente, atualmente uso o SequelPRO, como ele é apenas para MAC temos outra opção para Windows, o HeidiSQL, e para Linux temos o TeamSQL.

Feita a configuração acima vamos criar duas pastas na raiz do projeto, a pasta database e a pasta app, com elas criadas mova as pastas migrations e seeders para dentro de database e a pasta models para dentro de app, a estrutura deve ficar assim:

/--NodeSequelize
/----app
/------models
/--------index.js
/----config
/------database.js
/----database
/------migrations
/------seeders
/----node_modules
/----.editorconfig
/----.eslintrc
/----.gitignore
/----index.js
/----package.json
/----yarn.lock ou package.lock.json

O próximo passo é configurar o Sequelize para encontrar os arquivos nas pastas pra onde os movemos, para isso na raiz do projeto crie um arquivo .sequelizerc e insira nele o conteúdo:

const path = require('path');

module.exports = {
  'config': path.resolve('config', 'database.js'),
  'models-path': path.resolve('app', 'models'),
  'seeders-path': path.resolve('database', 'seeders'),
  'migrations-path': path.resolve('database', 'migrations'),
};
NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

Para entender mais sobre a estrutura desse arquivo ou sua função exata você pode visitar esse link.

Nesse ponto o Sequelize já deve estar reconhecendo corretamente os caminhos dos seus arquivos. O próximo passo é configurar os models da aplicação, os models 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 código.

Primeiro vamos configurar o arquivo app/models/index.js que é o responsável por importar os outros models da aplicação, seu código limpo e atualizado com as novas features do ES6 deve ficar assim:

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const config = require('../../config/database.js');

const db = {};
const sequelize = new Sequelize(config);

fs
  .readdirSync(__dirname)
  .filter(file => (file.indexOf('.') !== 0) && (file !== path.basename(__filename)) && (file.slice(-3) === '.js'))
  .forEach((file) => {
    const model = sequelize.import(path.join(__dirname, file));
    db[model.name] = model;
  });

Object.keys(db).forEach((modelName) => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;

Obs.: Ainda não entende muito bem de Javascript e as features do ES6/ES7/ES8!? Tá esperando o que pra correr e ver nossos cursos gratuitos sobre esses assuntos? Não perca tempo, corre lá antes de continuar a configuração 😉


E antes de criarmos o model de Usuário falta só mais uma configuração (prometo que só mais uma), precisamos criar as migrations, que são os arquivos que guardam as versões da base de dados, por exemplo, quando você ou alguém do seu time modifica a estrutura da tabela a migration que é a responsável por guardar essa mudança para que todos os desenvolvedores possam atualizar sua base de dados com ela.

E para criar nossa primeira migration, a de Usuário, basta executar:

node_modules/.bin/sequelize migration:create --name=create-users
// ou
// npx sequelize migration:create --name=create-users

Assim que o comando for executado deve ser criado na sua pasta migrations um arquivo, se você abri-lo verá uma estrutura com duas funções, a up, que é a função que indica o que modificar no banco de dados quando executarmos a migration e a down, que funciona como um rollback, ou seja, tudo que for feito na up deve ser desfeito na down.

O arquivo de migration limpo e configurado para criar nossa tabela de Usuário ficou assim:

module.exports = {
  up: (queryInterface, DataTypes) => {
    return queryInterface.createTable('Users', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: DataTypes.INTEGER,
      },
      name: {
        allowNull: false,
        type: DataTypes.STRING,
      },
      email: {
        allowNull: false,
        type: DataTypes.STRING,
        unique: true,
      },
      password: {
        allowNull: false,
        type: DataTypes.STRING,
      },
      createdAt: {
        allowNull: false,
        type: DataTypes.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: DataTypes.DATE,
      },
    });
  },

  down: (queryInterface) => {
    return queryInterface.dropTable('Users');
  }
};

Nesse ponto podemos testar se está tudo funcionando corretamente executando o comando:

node_modules/.bin/sequelize db:migrate
// ou
// npx sequelize db:migrate

É bem provável que apareça um erro no seu terminal ao tentar executar o comando acima, isso se dá pelo fato de o Sequelize precisar de um pacote específico do banco de dados que você definiu no arquivo config/database.js, como estamos usando o MySQL precisamos instalar o pacote mysql2, faça isso com o comando:

npm install mysql2
// ou
// yarn add mysql2

Após a instalação execute novamente o comando db:migrate e dessa vez tudo deve funcionar, para verificar abra o seu banco de dados e verifique se no database crud_sequelize foram criadas as tabelas SequelizeMeta e Users, a tabela SequelizeMeta que foi criada guarda informações sobre as migrations que já foram executadas, para que na próxima execução ele execute apenas o que houver de novo, e não tudo do começo.

Agora sim vamos à criação do model de Usuários (Aleluia rsrs), para começarmos vamos criar um arquivo user.js dentro da pasta app/modelse seu conteúdo deve ficar da seguinte maneira:

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    name: DataTypes.STRING,
    email: DataTypes.STRING,
    password: DataTypes.STRING,
  });

  return User;
}

Para saber mais sobre a definição de um model você pode entrar nesse link.

Ufa, agora sim acabaram as configurações, falta apenas testar se o 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 assim:

const { User } = require('./app/models');

E como é o arquivo index podemos suprimi-lo da importação, e depois vamos criar um usuário logo abaixo da linha de configuração do Body Parser, para isso vamos usar um comando do model que o Sequelizedisponibiliza, ficando:

User.create({ name: 'Claudio', email: 'claudio@rocketseat.com.br', password: '123456' });

Para ver os detalhes sobre o uso dos models você pode entrar nesse link.

Se tudo der certo ao executar o seu projeto com o comando node index.jsdeverá ser criado um registro no banco de dados crud_sequelize na tabela Users.


Ufa, nesse pontos já temos o Sequelize configurado e pronto para começarmos o desenvolvimento do CRUD, você pode encontrar o projeto até esse ponto nesse link.

NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

Criando o CRUD de Usuários

Para que o post não se estenda muito vou mostrar como criar os métodos de CRUD diretamente nas rotas no index.js da raiz do projeto, as rotas criadas foram:

app.get('/users', (req, res) => {}); //Listar todos
app.post('/users', (req, res) => {}); // Criar
app.get('/users/:id', (req, res) => {}); //Buscar
app.put('/users/:id', (req, res) => {}); //Editar
app.delete('/users/:id', (req, res) => {}); //Deletar

Os nomes são quase que auto descritivos sobre a função de cada uma, portanto bora pro código delas. Seguindo a documentação nesse link a função para registro de um novo usuário ficou assim:

app.post('/register', async (req, res) => {
  const user = await User.create(req.body);
  res.json(user);
});

As demais funções deixo como desafio pra vocês implementarem e deixarem um feedback sobre o que acharam e se tiveram alguma dificuldade.

O link da documentação dos métodos que podem ser usados no model estão nesse link.

O projeto final você pode encontrar –> nesse link <–

Conclusão

Estamos chegando ao final do post e como vocês devem ter percebido o Sequelize é um grande facilitador para o desenvolvimento de aplicações, mas não só ele como a maioria dos ORM’s, seu princípio é o que permite que o banco de dados seja mapeado em classes e abstraia toda a lógica de manipulação do banco de dados.

E por hoje é isso pessoal, espero que tenham gostado, mesmo o post tendo ficado um pouco extenso, mas tentei resumir tudo de uma forma que vocês vissem todos os detalhes da configuração.


E para reforçar ou iniciar o seu aprendizado sobre Javascript, ES6/ES7/ES8 corre lá e assiste nossos cursos gratuitos sobre esses assuntos!


Se você chegou até aqui não esquece de deixar seu comentário com um feedback, sugestão ou crítica (desde que seja construtiva).

Abraços! e até a próxima Devs 😉

NLW Expert | Evento gratuito de programação na prática | Rocketseat
Desafie-se em uma nova tecnologia criando um projeto completo em 3 aulas no maior evento online e gratuito de programação na prática para todos os níveis da Rocketseat.

Marcadores