Você já teve vontade ou precisou criar uma API, mas pensou ser algo difícil de fazer?
O Node Js vem se destacando nos últimos tempos por ser uma ferramenta extremamente ágil no desenvolvimento back-end.
Veja como é fácil construir uma API REST utilizando essa incrível ferramenta.
Passo #1: Criação da estrutura
O primeiro passo para o desenvolvimento de uma API é a criação da sua estrutura de pastas.
Para isso, crie uma pasta onde o seu projeto será salvo.
Em seguida, através da linha de comando (Terminal, CMD ou Powershell), rode o comando abaixo para iniciar seu projeto.
yarn init -y
Com o projeto criado, utilize o comando abaixo para instalar as dependências do nosso seu projeto.
yarn add express sequelize mysql2
Express é o framework que utilizaremos.
Sequelize é o ORM que utilizaremos para fazer a comunicação com o banco de dados.
MySQL2 é o módulo necessário para o uso do mysql junto ao sequelize.
Utilize o comando abaixo para instalar a ferramenta de linha de comando do sequelize.
yarn add sequelize-cli -D
Nesse momento, sua estrutura de pastas deve estar semelhante à essa:

Passo #2: Configuração do Sequelize
Para configurar o sequelize, crie um arquivo na raiz do seu projeto, com o nome .sequelizerc
Com esse arquivo criado, precisamos informar algumas configurações de pastas do nosso projeto.
Seu arquivo .sequelizerc deverá conter o seguinte conteúdo:
const { resolve } = require('path');
module.exports = {
config: resolve('src', 'config', 'database.js'),
'models-path': resolve('src', 'app', 'models'),
'seeders-path': resolve('src', 'database', 'seeders'),
'migrations-path': resolve('src', 'database', 'migrations'),
}
Com as modificações feitas, rode o comando abaixo para iniciar o sequelize no seu projeto.
sequelize init
Após iniciar o sequelize, sua estrutura deve estar semelhante à esse:

Agora, precisamos fazer algumas modificações no arquivo database.js criado pelo sequelize. O arquivo pode ser encontrado dentro da pasta src/config
O conteúdo do arquivo deve ficar assim:
module.exports = [
development: {
dialect: 'mysql',
host: '127.0.0.1',
port: 3306,
username: 'admin',
password: '',
database: 'api',
operatorAliases: false,
define: {
timestamps: true,
underscored: true,
underscoredAll: true,
},
},
];
Lembre-se de alterar as o host, username e password de acordo com as suas configuração do seu banco, e de criar o banco api ou alterar o arquivo para o nome do banco que você criar.
Caso você ainda não tenha criado o banco de dados, basta rodar o comando sequelize db:create que o sequelize criará a tabela com o nome que foi definido no campo database.
Passo #3: Criação da migration
As migrations são ferramentas suportadas pelo sequelize, para manter o versionamento das tabelas do banco de dados, através do código.
Criaremos agora a migration de usuários, com o seguinte comando:
sequelize migration:create --name create-users
Perceba que na pasta src/database/migration existe um novo arquivo, essa é a migration que acabamos de criar.
Essa migration ainda não possui todas as informações dos dados necessários.
Para isso, precisamos adicionar algumas informações referentes aos tipos que dados que a tabela terá.
Sua migration deve ficar da seguinte forma:
module.exports = {
up: (queryInterface, Sequelize) => queryInterface.createTable('users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER,
},
name: {
allowNull: false,
type: Sequelize.STRING,
},
email: {
allowNull: false,
type: Sequelize.STRING,
},
phone: {
allowNull: false,
type: Sequelize.DOUBLE,
},
created_at: {
allowNull: false,
type: Sequelize.DATE,
},
updated_at: {
allowNull: false,
type: Sequelize.DATE,
},
}),
down: queryInterface => queryInterface.dropTable('users'),
};
A propriedade allowNull diz se o campo deverá aceitar valores nulos ou não.
A propriedade primaryKey diz se o campo será do tipo chave primária.
Os campos created_at e created_at servirão para salvarmos a data de criação e de edição de cada linha na tabela.
Com a migration criada, rode o comando abaixo para que a tabela seja criada no seu banco de dados.
sequelize db:migrate
Passo #4: Criação do model
Na arquitetura MVC, o model é a representação da tabela do banco de dados.
Para criarmos o model de usuários, comece criando uma pasta chamada models dentro de src/app.
Dentro da pasta models, crie um arquivo chamado User.js
Adicione o seguinte conteúdo à ele:
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User', {
name: DataTypes.STRING,
email: {
type: DataTypes.STRING,
validate: {
isEmail: true,
},
},
phone: {
type: DataTypes.DOUBLE,
validate: {
len: [8, 12],
},
},
});
return User;
};
Utilizamos a função define para definirmos o nosso model.
O primeiro parâmetro é uma string contendo o nome do model.
O segundo parâmetro é um objeto contendo os campos da tabela.
Nos atributos, podemos definir diretamente o tipo dele, como fizemos com o campo name, ou podemos passar um objeto, caso desejemos passar algumas propriedade a mais, como fizemos com o email e o phone.
No campo email, adicionamos a propriedade validate e nela, passamos o valor isEmail: true para dizer que esse campo é o do tipo email.
No campo phone, adicionamos a propriedade validate e nela, passamos o valor len: [8, 12] para especificar o tamanho do dado que deve ser aceito, nesse caso, serão aceitos apenas valores com o tamanho maior que 8 e menor que 12 caracteres.
Passo #5: Criação do Controller
O Controller será o responsável pelo intermédio entre as rotas e os models da nossa aplicação, nele, serão criada as actions que serão acessadas através das nossas rotas.
Começaremos criando uma pasta chamada controllers dentro de src/app.
Dentro da pasta controllers, crie um arquivo chamado UserController.js
Nesse arquivo, criaremos as actions referentes ao usuário.
const { User } = require('../models');
class UserController {
async index(req, res) {
try {
const users = await User.findAll();
return res.json(users);
} catch (err) {
return res.status(400).json({ error: err.message });
}
}
async show(req, res) {
try {
const user = await User.findByPk(req.params.id);
return res.json(user);
} catch (err) {
return res.status(400).json({ error: err.message });
}
}
async store(req, res) {
try {
const user = await User.create(req.body);
return res.json(user);
} catch (err) {
return res.status(400).json({ error: err.message });
}
}
async update(req, res) {
try {
const user = await User.findByPk(req.params.id);
await user.update(req.body);
return res.json({ user });
} catch (err) {
return res.status(400).json({ error: err.message });
}
}
async destroy(req, res) {
try {
const user = await User.findByPk(req.params.id);
await user.destroy();
return res.json();
} catch (err) {
return res.status(400).json({ error: err.message });
}
}
}
module.exports = new UserController();
Neste controller, nós temos uma action para cada operação básica, são elas:
- index – Lista os registros da tabela
- show – Retorna os dados de um registro específico
- store – Salva o novo item na tabela
- update – Atualiza um registro existente
- destroy – Exclui um registro específico
Passo #6: Criação das rotas
Como você já deve saber, a comunicação em uma API se dá através das rotas.
Para criar as rotas, crie um arquivo chamado routes.js dentro da pasta src.
Adicione ao arquivo routes.js o seguinte conteúdo:
const { Router } = require('express');
const UserController = require('./app/controllers/UserController');
const routes = Router();
routes.get('/users', UserController.index);
routes.get('/users/:id', UserController.show);
routes.post('/users', UserController.store);
routes.put('/users/:id', UserController.update);
routes.delete('/users/:id', UserController.destroy);
module.exports = routes;
Perceba que cada action que criamos no UserController possui uma rota especifica de acesso à essa action.
Passo #7: Configuração do servidor
Para finalizar nossa aplicação, precisamos definir as configurações do servidor.
Para isso, crie um arquivo chamado index.js dentro da pasta src.
Nele, adicione o seguinte código:
const express = require('express');
const routes = require('./routes');
const app = express();
app.use(express.json());
app.use(routes);
app.listen(3333);
Nesse arquivo, nós fazemos a importação das rotas que configuramos no passo anterior e definimos qual porta nosso servidor deve escutar.
Para startar seu servidor, basta iniciar o node no arquivo index.js que acabamos de cria.
node src/index.js
Para testar nossa api, podemos o insomnia, que é um cliente REST, específico para testes de requisições.
Demonstração
Abaixo você pode conferir uma demonstração do projeto:
Forte Abraço,
Carlos Levir
Estranho.
Após instalar o CLI do Sequelize, ao rodar o comando “sequelize init”, ocorre o seguinte erro:
‘sequelize’ não é reconhecido como um comando interno
ou externo, um programa operável ou um arquivo em lotes.
Será que está faltando algo?
Fala André, beleza?
Você instalou a CLI globalmente ou somente no projeto? Verifica se você está dentro da pasta do projeto 🙂
Caso esteja no windows, tenta reiniciar sua máquina.
Grande Abraço 😀
npm install -g sequelize-cli yarn sequelize
Otimo tudo, muito completo, so um detalhe para o erro que esta dando, aqui esta corrigido:
module.exports = {
development: {
dialect: ‘mysql’,
host: ‘127.0.0.1’,
port: 3306,
username: ‘admin’,
password: ”,
database: ‘api’,
operatorAliases: false,
define: {
timestamps: true,
underscored: true,
underscoredAll: true,
},
},
};
Opa Maurício, estranho precisar disso, talvez o sequelize tenha atualizado algo. Obrigado por compartilhar sua solução 😀
Grande Abraço 🙂
Eu tento executar o db:migrate e aparece o seguinte erro: “Loaded configuration file “src\config\database.js”.
ERROR: Dialect needs to be explicitly supplied as of v4.0.0″
alguém passou por isso e consegue ajudar?
Faaala Rudson, verifica se no seu arquivo database.js você definiu o valor dialect: ‘mysql’, 🙂
Fala Carlos, tudo bem ?
Gostei muito do conteúdo parabéns!!
Porem estou com uma duvida na controller. Sempre que é criada uma controller ela deve conter essa estrutura de métodos ?
index – Lista os registros da tabela
show – Retorna os dados de um registro específico
store – Salva o novo item na tabela
update – Atualiza um registro existente
destroy – Exclui um registro específico
Se sim, é possível ter mais de um método show em uma controller por exemplo ?
desde já obrigado pela atenção.
Fala Edvaldo, essa é a estrutura padrão, você não precisa implementar todos os métodos, mas não é uma boa prática criar métodos além desses, nesse caso o melhor é criar um novo controller 😉
Parabéns pelo tutorial, consegui fazer a implementação descrita no artigo com sucesso….funcionou perfeitamente….valeu
Sucesso, Paulo!
Parabéns pelo conteúdo!
Obrigado, Talita!
Cara, muito bom o seu post. Bem didático, simples e direto. Parabéns!!!
Obrigado, Marcus!
Melhor comentário que leio a tempos: “Caso esteja no windows, tenta reiniciar sua máquina.”