Dominar a estruturação de projetos backend através da arquitetura Model-View-Controller (MVC), uma abordagem padrão para organizar o código em componentes distintos de model, view e controller. Isso facilita a manutenção e a escalabilidade do projeto.
Feedback: As rotas são configuradas para utilizar os métodos apropriados do controller, seguindo a estrutura RESTful para operações CRUD.
Verdadeiro ou Falso: Na arquitetura MVC, o Controller é responsável por validar os dados recebidos da View.
A) Verdadeiro
B) Falso
Resposta correta
Verdadeiro ou Falso: Na arquitetura MVC, o Controller é responsável por validar os dados recebidos da View.
Resposta Correta: A
Feedback: Verdadeiro. O Controller é responsável por processar as solicitações do usuário, incluindo a validação dos dados recebidos e a interação com os Models.
Qual comando usamos para instalar o pacote dotenv para carregar variáveis de ambiente?
A) npm install dotenv
B) npm install env
C) npm install dotenv-cli
D) npm install environment
Resposta correta
Qual comando usamos para instalar o pacote dotenv para carregar variáveis de ambiente?
Resposta Correta: A
Feedback: O comando npm install dotenv é usado para instalar o pacote dotenv, que carrega variáveis de ambiente de um arquivo .env para process.env.
Qual é a principal vantagem de usar a arquitetura MVC em um projeto?
A) Reduzir o tempo de desenvolvimento.
B) Melhorar a organização e a separação de responsabilidades no código.
C) Facilitar a criação de interfaces gráficas.
D) Aumentar a velocidade de execução do código.
Resposta correta
Qual é a principal vantagem de usar a arquitetura MVC em um projeto?
Resposta Correta: B
Feedback: A arquitetura MVC melhora a organização e a separação de responsabilidades no código, facilitando a manutenção e a escalabilidade do projeto.
Exercícios de Validação
Esses exercícios testarão sua compreensão prática. Revise o feedback para melhorar suas habilidades.
Desafio de Código
Fornecemos um arquivo index.js que contém um endpoint simples. Separe esse código em um projeto seguindo a arquitetura MVC, criando os arquivos necessários para organizar o projeto em Models, Views e Controllers.
Arquivo Inicial
index.js
constexpress=require('express');constapp=express();app.use(express.json());constprodutos= [];app.post('/produtos', (req, res) => {constnovoProduto=req.body;if (!novoProduto.nome ||!novoProduto.preco ||!novoProduto.categoria) {returnres.status(400).send('Corpo da requisição deve conter as propriedades nome, preço e categoria.'); }produtos.push(novoProduto);res.status(201).send(novoProduto);});app.listen(3000, () => {console.log(`Servidor rodando em http://localhost:3000`);});
Mova a lógica de validação e criação do produto para o controller no arquivo produto.controller.js.
Implementação dos Services:
Mova a lógica de manipulação de dados para o service no arquivo produto.service.js.
Configuração das Rotas:
Configure as rotas no arquivo produto.router.js para utilizar os métodos do controller.
Atualização do Servidor:
Atualize o arquivo index.js para usar as rotas configuradas.
Código Esperado
src/produto/produto.controller.js
constservice=require('./produto.service');asyncfunctioncreate(req, res) {constnovoProduto=req.body;if (!novoProduto.nome ||!novoProduto.preco ||!novoProduto.categoria) {returnres.status(400).send('Corpo da requisição deve conter as propriedades nome, preço e categoria.'); }awaitservice.create(novoProduto);res.status(201).send(novoProduto);}module.exports= { create};
constexpress=require('express');constprodutoRouter=require('./src/produto/produto.router');constapp=express();app.use(express.json());app.use('/produtos', produtoRouter);app.listen(3000, () => {console.log(`Servidor rodando em http://localhost:${port}`);});
{%
endcode %}
Feedback: Certifique-se de que a lógica de validação está no controller e a lógica de manipulação de dados está no service. Configure as rotas corretamente para usar o controller.
Revisão de Código
Analise o código a seguir, encontre e corrija o erro relacionado à separação de responsabilidades na arquitetura MVC.
index.js
constexpress=require('express');const { MongoClient,ObjectId } =require('mongodb');constapp=express();app.use(express.json());constdbUrl=process.env.DATABASE_URL;constclient=newMongoClient(dbUrl);asyncfunctionmain() {awaitclient.connect();constdb=client.db('app');constcollection=db.collection('produtos');app.post("/produtos",asyncfunction (req, res) {constnovoItem=req.body;if (!novoItem.nome ||!novoItem.preco ||!novoItem.categoria) {returnres.status(400).send('Corpo da requisição deve conter as propriedades nome, preço e categoria.'); }awaitcollection.insertOne(novoItem);res.status(201).send(novoItem); });app.listen(3000,function () {console.log(`Aplicação rodando em http://localhost:3000`); });}main();
Resposta Correta
Erros:
A lógica de manipulação de dados deve ser movida para o service para manter a separação de responsabilidades.
O código de validação e criação de produtos deve ser movido para o controller.
src/produto/produto.controller.js
constservice=require('./produto.service');asyncfunctioncreate(req, res) {constnovoItem=req.body;if (!novoItem.nome ||!novoItem.preco ||!novoItem.categoria) {returnres.status(400).send('Corpo da requisição deve conter as propriedades nome, preço e categoria.'); }awaitservice.create(novoItem);res.status(201).send(novoItem);}module.exports= { create};
Feedback: Certifique-se de que a lógica de manipulação de dados está no service e a lógica de controle está no controller para manter a separação de responsabilidades conforme a arquitetura MVC.
Projeto Prático
Reestruture uma aplicação Node.js existente para seguir a arquitetura MVC. A aplicação deve gerenciar uma entidade "Produtos" com as propriedades "nome", "preço" e "categoria". Crie os arquivos necessários para organizar o projeto em Models, Views e Controllers, e implemente operações CRUD para a entidade "Produtos".
Tarefas
Configuração Inicial:
Inicialize um novo projeto NodeJS.
Instale o ExpressJS e o MongoDB Driver.
Configure o Nodemon para reiniciar o servidor automaticamente.
Crie um arquivo .env e adicione as variáveis de ambiente necessárias.
Configure a conexão com o MongoDB utilizando o MongoClient e as variáveis de ambiente no arquivo database-connection.js.
Implementação dos Controllers:
Implemente os métodos do controller para operações CRUD no arquivo produto.controller.js.
Implementação dos Services:
Implemente os métodos de acesso aos dados no arquivo produto.service.js.
Configuração das Rotas:
Configure as rotas no arquivo produto.router.js para utilizar os métodos do controller.
Inicialização do Servidor:
Configure a inicialização do servidor no arquivo index.js e adicione as rotas.
Código Esperado
src/db/database-connection.js
const { MongoClient } =require('mongodb');constdbUrl=process.env.DATABASE_URL;constdbName='mvc-produtos';constclient=newMongoClient(dbUrl);asyncfunctionconnectToDatabase() {console.log('Conectando ao banco de dados...');awaitclient.connect();console.log('Banco de dados conectado com sucesso!');}functiongetDatabase() {returnclient.db(dbName);}module.exports= { connectToDatabase, getDatabase};
src/produto/produto.controller.js
constservice=require('./produto.service');asyncfunctionreadAll(req, res) {constitems=awaitservice.readAll();res.send(items);}asyncfunctionreadById(req, res) {constid=req.params.id;constitem=awaitservice.readById(id);if (!item) {returnres.status(404).send('Produto não encontrado.'); }res.send(item);}asyncfunctioncreate(req, res) {constnovoItem=req.body;if (!novoItem ||!novoItem.nome ||!novoItem.preco ||!novoItem.categoria) {returnres.status(400).send('Corpo da requisição deve conter as propriedades nome, preço e categoria.'); }awaitservice.create(novoItem);res.status(201).send(novoItem);}asyncfunctionupdateById(req, res) {constid=req.params.id;constnovoItem=req.body;if (!novoItem ||!novoItem.nome ||!novoItem.preco ||!novoItem.categoria) {returnres.status(400).send('Corpo da requisição deve conter as propriedades nome, preço e categoria.'); }awaitservice.updateById(id, novoItem);res.send(novoItem);}asyncfunctiondeleteById(req, res) {constid=req.params.id;awaitservice.deleteById(id);res.send('Produto removido com sucesso: '+ id);}module.exports= { readAll, readById, create, updateById, deleteById};
Verificação dos Endpoints: Certifique-se de testar cada rota (/produtos, /produtos/:id, /produtos com POST, PUT e DELETE) acessando http://localhost:3000 e verificando as respostas.
Estrutura do Projeto: Verifique se a estrutura de pastas segue o padrão MVC, com Models, Views e Controllers bem definidos.
Uso de Variáveis de Ambiente: Certifique-se de que as informações sensíveis, como a URL do banco de dados, estão sendo carregadas do arquivo .env.