Olá a todos!
Fiz o curso e achei o projeto muito bom. Por isso, quis aperfeiçoar um pouco o código, focando na parte das resposta de sucesso (status 200).
As respostas de sucesso estavam sendo definidas dentro do código de cada controller. E para cada controler era necessário colocar:
res.status(200).send(objeto)
O desafio que proponho é refatorar o código de forma que seja criado um middleware para tratamento personalizado das mensagens de sucesso, usando como base os conhecimentos utilizados para construir toda a parte de tratamento de erros, separando a responsabilidade do código para que ele tenha arquivos específicos responsáveis por essas respostas. colocar informações como a página atual e o número total de páginas da consulta.
Seguem as alterações que eu realizei:
Obs: Os códigos dos arquivos pode ser verificados neste repositório
Criação de uma pasta dentro de
srcchamadasucessDentro desta pasta, criar os seguintes arquivos com as classes responsáveis pelas mensagens de sucesso:
- Arquivo
SucessBase.js - Arquivo
SucessPost.js - Arquivo
SucessPut.js - Arquivo
SucessDelete.js
- Arquivo
Criar um novo arquivo na pasta middleware que receberá as requisições bem sucessidas e irá tratar os dados recebidos pelo parâmetro
req. Perceba que neste arquivo será importado as classes criadas anteriormente, e, de acordo com o método HTTP, é chamada a respectiva classe com a mensagem de sucesso:
Arquivo sucess.js
const resultado = {
dados: req.resultado,
paginaAtual: req.paginaAtual,
totalPaginas: Math.ceil(req.totalRegistros / req.limiteAtual)
};
if (resultado === null) {
next(new NaoEncontrado("Id não localizado"))
} else if (req.method == 'POST') {
new SucessPost(resultado).sendResponse(res)
} else if (req.method == "PUT") {
new SucessPut(resultado).sendResponse(res)
} else if (req.method == 'DELETE') {
new SucessDelete().sendResponse(res)
} else {
new SucessBase(resultado).sendResponse(res)
};
- No da função do arquivo anterior criamos um objeto chamado
resultado, cujo os valores são propriedades personalizadas no parâmetroreqque vem dos controllers e do middlewarepaginate.js. Para receber essas propriedades personalizadas, precisamos alterar os códigos da seguinte forma:
Arquivo livrosController.js:
Fazemos a atribuição de req.resultados logo após a declarações da variável livrosResultado e inserimos a declaração next(). Isso pode replicado em todos as funções dos controllers.
Exemplo do método listarLivroPorId:
Código Refatorado
const id = req.params.id;
const livroResultados = await livros.findById(id)
req.resultado = livroResultados
next()
Adicionalemente, nos métodos que passarão pelo paginate, ou seja, retornarão vários resultados em páginas, colocamos um declaração adicional com a quatidade total de registros da seguinte forma:
Exemplo do método listaLivros:
const totalRegistros = await livros.countDocuments()
req.totalRegistros = totalRegistros
Esse processo de refatoração pode ser repetido para todas as funções dos controladores.
Obs.: Em alguns métodos, optei por exibir apenas o Id do objeto ao invés de todo o objeto como em cadastrarLivro ou atualizarLivro. Para isso utilizei o seguinte código:
req.resultado = livroResultado !== null ? livroResultado._id : null
Arquivo paginate.js:
Encontre o código de buscaResultado abaixo e acrescente as linhas indicadas:
const buscaResultado = await req.resultado.find()
.sort({[campoOrdenacao] : ordem})
.skip((pagina-1)*limite)
.limit(limite);
// Código adicionado
req.resultado = buscaResultado;
req.paginaAtual = pagina
req.limiteAtual = limite
next()
- Por fim, adicione o meddleware
sucessao final das rotas no arquivolivrosRoutes.js:
import sucess from "../middlewares/sucess.js";
const router = express.Router();
router
.get("/livros", LivroController.listarLivros, paginate, sucess)
.get("/livros/busca", LivroController.listarLivroPorFiltro, paginate, sucess)
.get("/livros/:id", LivroController.listarLivroPorId, sucess)
.post("/livros", LivroController.cadastrarLivro, sucess)
.put("/livros/:id", LivroController.atualizarLivro, sucess)
.delete("/livros/:id", LivroController.excluirLivro, sucess)
Por conta da limitação de caracteres, acabei abstratindo alguns códigos, mas acredito que deu pra entender a idéia do desafio.