No artigo anterior configuramos nosso projeto, agora chegou a hora de configurar nossa conexão com o sequelize.
Vamos começar
Primeiro precisamos criar um arquivo na raiz do projeto chamado .sequelizerc, este será responsável por mapear cada pasta que o sequelize vai usar de acordo com nossa estrutura de pastas.
E agora vamos começar a criar alguns arquivos importantes para que o sequelize gere a parte de migrations, seeds e também possa conectar com a instância do banco de dados.
OBS: Neste arquivo temos uma particularidade, ele não está usando o import/export , infelizmente o sequelize-cli roda usando o commonJS então esse arquivo de configuração necessita estar em commonJS
src/database/index.js
import Sequelize from 'sequelize';
import databaseConfig from '../config/database';
const models = [];
class Database {
constructor(){
this.init();
}
init(){
this.connection = new Sequelize(databaseConfig);
models.map((model) => model.init(this.connection))
.map((model) => {
if(model.associate) model.associate(this.connection.models);
return model;
})
}
}
export default new Database();
Antes de prosseguir precisamos instalar uma dependência chamada mysql2 para isso:
yarn add mysql2
Para prosseguir precisamos entender mais alguns conceitos, que são o migrations e seeds.
Migrations: São classes que executaram promises capazes de gerar nossa estrutura na base de dados, ele irá gerar as tabelas, relacionamentos e campos por etapas, para cada nova tabela teremos uma nova migration, não precisa se preocupar o migrate sabe identificar qual foi a última executada.
Seeds: São classes que executam promises capazes de gerar dados padrões para as tabelas, seja para mockar ou gerar dados padrões para tabelas.
Para criar uma migration basta rodarmos o seguinte comando:
Se tudo correr bem e o sequelize conseguir conectar com o banco você receberá a seguinte mensagem:
E perceberá que na pasta src/database/migrations e haverá um novo arquivo e abriremos ele para configurar a tabela de alunos e vamos seguir a seguinte configuração:
up: Responsável por executar uma criação/alteração de tabela
down: Responsável por executar métodos de desfazer alterações como por exemplo , se o up está criando a tabela aluno, no down colocamos seu drop, pois é o comando que será executado ao reverter a migration já executada.
Agora que criamos nossa migration de aluno, faremos o mesmo processo para o curso:
E assim que for criado a nossa migration de curso iremos criar sua classe igual fizemos com a de usuário, estabelecendo o up e o down baseado no nosso escopo de banco de dados apresentado anteriormente.
Agora a única alteração que faltou colocarmos nessa migration é o vínculo entre o curso e o aluno, uma questão que pode surgir nesse momento é porque não adicionamos o campo com relacionamento no aluno enquanto estávamos criando sua classe , bom a resposta disso é simples! como não havíamos criado a migration de curso se tivéssemos tentado rodar essas migrations receberíamos um erro dizendo que a tabela não existe, então iremos adicionar esse campo de relacionamento na nossa próxima criação de migration abaixo.
Em references iremos dizer com qual model ele terá relacionamento e em key será qual o campo que sofrerá esse relacionamento, logo em seguida precisamos dizer o que vai acontecer ao registro quando for atualizado ou deletado com os parâmetros (onUpdate, onDelete).
Agora que criamos todas nossas migrations necessárias vamos rodá-las e ver se tudo correu bem, para isso devemos rodar o seguinte comando:
yarn sequelize db:migrate
Se tudo correr bem, teremos o seguinte resultado:
Isso significará que tudo correu bem, para que você entenda como o sequelize trabalha abra seu gerenciador de banco de dados, e vamos ver o que o sequelize criou no banco de dados que informamos para ele!
Como podemos ver após ter rodado a migration foram geradas as tabelas que criamos via classe e o sequelize criou uma tabela extra chamada sequelizemeta está pasta é muito importante para o funcionamento é através dela que o sequelize sabe qual foi a última migration executada para que na próxima vez que o comando seja executado ele continue da última migration executada.
Agora que temos nossas tabelas criadas vamos criar suas respectivas classes para que o node possa fazer inclusões através do nosso ORM, vamos começar criando o CRUD básico para curso.
Para isso iremos até a pasta de models dentro de “src/app/models” e criaremos um arquivo chamado Curso.js
src/app/models/Curso.js
import Sequelize, { Model } from "sequelize";
class Curso extends Model {
static init(sequelize) {
super.init(
{
nomecurso: Sequelize.STRING(100),
duracaocurso: Sequelize.STRING(100),
datapublicacao: Sequelize.DATE
},
{
sequelize,
}
);
return this;
}
}
export default Curso
Agora temos uma classe vinculada ao sequelize, como se fosse o reflexo da nossa migration, a partir de agora ao usar a classe Curso poderemos fazer qualquer operação no banco de dados, agora vamos configurar nosso controller para iniciar as primeiras inclusões no banco de dados
Vamos criar nosso primeiro controller, mas antes precisamos colocar alguns conceitos na cabeça! utilizar a metodologia Restful e seguir a regra de não deixar muitas funções em um único controller o recomendo é no máximo 5, sendo:
store: Onde iremos realizar a inclusão de uma informação
update: Onde iremos atualizar um registro referente a esse controller
delete: Onde realizamos a exclusão de alguma informação
index: Onde realizaremos a listagem dos itens incluídos neste controller
show: Onde realizaremos a visualização de um registro específico
Neste ponto todos os endpoints referente a cursos estão pronto para testar, lembrando sempre de seguir o seguinte modelo:
Get: Quando for uma consulta que não enviará informações no maximo uma query;
Post: Para realizar um processo ou incluir novos registro
Put: Para atualizar um registro
Delete: Para excluir um registro
OBS: Essa é a forma que denominamos cada método de uma requisição
Agora seguimos para a parte de aluno! Está parte será um pouco mais complexa! pois envolverá relacionamentos entre a tabela aluno X curso
Vamos começar criando o Model de Aluno!
src/app/models/Aluno.js
import Sequelize, { Model } from "sequelize";
class Aluno extends Model {
static init(sequelize) {
super.init(
{
nome: Sequelize.STRING(100),
dtnascimento: Sequelize.STRING(100),
telefone: Sequelize.DATE,
bairro:Sequelize.STRING(100),
cep: Sequelize.STRING(20)
},
{
sequelize,
tableName: 'aluno',
}
);
return this;
}
/**
* Sempre que um model tiver um relacionamento
* adicionaremos esse associate para indicar
* com que esse model se relaciona
*/
static associate(models){
/**
* Neste caso usaremos o belongsTo, mas dependendo da necessidade
* temos outras opçoes
* belongsToMany, belongsTo, HasMany, HasOne,Association
* para conhecer mais acesse:
* https://sequelize.org/master/class/lib/associations/belongs-to.js~BelongsTo.html
*/
this.belongsTo(models.Curso, {
foreignKey: 'curso_id',
as: 'curso',
});
}
}
export default Aluno
OBS: Em belongsTo colocaremos o model que terá o relacionamento e um objeto indicando qual é o campo que sofre o relacionamento na tabela “Aluno” e como chamaremos esse relacionamento na hora que precisar exibir em uma consulta.
OBS²: Como adicionamos um novo model precisamos adicionar ele no nosso arquivo de database/index.js ficando da seguinte forma
src/database/index.js
import Sequelize from 'sequelize';
import databaseConfig from '../config/database';
import Curso from '../app/models/Curso';
import Aluno from '../app/models/Aluno';
const models = [Curso,Aluno];
class Database {
constructor(){
this.init();
}
init(){
this.connection = new Sequelize(databaseConfig);
models.map((model) => model.init(this.connection))
.map((model) => {
if(model.associate) model.associate(this.connection.models);
return model;
})
}
}
export default new Database();
Feito isso nossa API está pronto para receber o controller de alunos e endpoints!
Então vamos lá !
Criaremos um controller para o aluno da seguinte forma:
OBS: Nesse controller temos algo novo, dentro dos métodos do model que realiza conexão do banco de dados, agora incluímos algumas opções no objeto vamos conhecê-los:
attributes: Indicamos quais campos queremos que seja retornado
include: Inserimos quais models estão relacionados com esse para exibir no retorno da consulta
Exemplo do retorno
Bom agora que já temos nosso model e controllers criados precisamos adicioná-los para nossas rotas!
Quando falamos em gestão de um time de engenharia de software, os principais desafios que vem à cabeça são como estimar as atividades, e como lidar com as expectativas dos
Se você trabalha na área de engenharia de software, e se interessa por gestão de projetos, com certeza já deve ter ouvido falar na metodologia Shape-up ou no produto desenvolvido
No desenvolvimento ágil, métricas e estimativas de software são fundamentais para medir o desempenho e estimar o tempo necessário para concluir projetos de forma eficiente.Nesse artigo vou trazer um panorama