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
src
chamadasucess
Dentro 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âmetroreq
que 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
sucess
ao 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.