È meglio non usarlo affatto! Spiego, ed è quello che faccio anche spiegarlo.
La funzione next () che può avere qualsiasi nome e per convenzione è stata impostata su next. È indirettamente correlato alle operazioni (PUT, GET, DELETE, ...) che vengono generalmente eseguite sulla stessa risorsa URI, ad esempio/ user /: id
app.get('/user/:id', function (req,res,next)...)
app.put('/user/:id', function (req,res,next)...)
app.delete('/user/:id', function (req,res,next)...)
app.post('/user/', function ()...)
Ora se guardi app.get, app.put e app.delete usano lo stesso uri (/ user /: id), l'unica cosa che li differenzia è la loro implementazione. Quando la richiesta viene fatta (req) express inserisce prima il req in app.get, se una convalida creata perché quella richiesta non è per quel controller fallisce, passa il req ad app.put che è la prossima rotta nel file te e così sopra. Come visto nell'esempio seguente.
app.get('/user/:id', function (req,res,next){
if(req.method === 'GET')
//whatever you are going to do
else
return next() //it passes the request to app.put
//Where would GET response 404 go, here? or in the next one.
// Will the GET answer be handled by a PUT? Something is wrong here.
})
app.put('/user/:id', function (req,res,next){
if(req.method === 'PUT')
//whatever you are going to do
else
return next()
})
Il problema sta nel fatto che alla fine si passa il req a tutti i controller sperando che ce ne sia uno che fa quello che si desidera, attraverso la convalida del req. Alla fine tutti i controller finiscono per ricevere qualcosa che non fa per loro :(.
Quindi, come evitare il problema di next () ?
La risposta è davvero semplice
1- dovrebbe esserci un solo uri per identificare una risorsa
http: // IpServidor / colection /: resource / colection /: resource se il tuo URI è più lungo di quello, dovresti prendere in considerazione la creazione di un nuovo uri
Esempio http: // IpServidor / users / pepe / contatti / contacto1
2-Tutte le operazioni su questa risorsa devono essere eseguite rispettando l'idempotenza dei verbi http (get, post, put, delete, ...), quindi la chiamata a un URI ha davvero solo un modo di chiamare
POST http://IpServidor/users/ //create a pepe user
GET http://IpServidor/users/pepe //user pepe returns
PUT http://IpServidor/users/pepe //update the user pepe
DELETE http://IpServidor/users/pepe //remove the user pepe
Maggiori informazioni [ https://docs.microsoft.com/es-es/azure/architecture/best-practices/api-design#organize-the-api-around-resources[[1]
Vediamo il codice! L'implementazione concreta che ci fa evitare l'uso di next ()!
Nel file index.js
//index.js the entry point to the application also caller app.js
const express = require('express');
const app = express();
const usersRoute = require('./src/route/usersRoute.js');
app.use('/users', usersRoute );
Nel file usersRoute.js
//usersRoute.js
const express = require('express');
const router = express.Router();
const getUsersController = require('../Controllers/getUsersController.js');
const deleteUsersController = require('../Controllers/deleteUsersController.js');
router.use('/:name', function (req, res) //The path is in /users/:name
{
switch (req.method)
{
case 'DELETE':
deleteUsersController(req, res);
break;
case 'PUT':
// call to putUsersController(req, res);
break;
case 'GET':
getUsersController(req, res);
break;
default:
res.status(400).send('Bad request');
} });
router.post('/',function (req,res) //The path is in /users/
{
postUsersController(req, res);
});
module.exports = router;
Ora il file usersRoute.js fa quello che dovrebbe fare un file chiamato usersRoute, che è quello di gestire le rotte dell'URI / users /
// file getUsersController.js
//getUsersController.js
const findUser= require('../Aplication/findUser.js');
const usersRepository = require('../Infraestructure/usersRepository.js');
const getUsersController = async function (req, res)
{
try{
const userName = req.params.name;
//...
res.status(200).send(user.propertys())
}catch(findUserError){
res.status(findUserError.code).send(findUserError.message)
}
}
module.exports = getUsersController;
In questo modo si evita l'uso di next, si disaccoppia il codice, si guadagna in prestazioni, si sviluppa SOLID, si lascia la porta aperta per una possibile migrazione a microservizi e, soprattutto, è facile da leggere da un programmatore.
res.redirect('/')
vs.return res.redirect('/')
in questo tipo di situazione? Forse è solo meglio scrivere sempre return prima delle dichiarazioni res per evitare errori nell'impostare le intestazioni dopo che sono state inviate?