It is best not to use it at all! I explain, and that is what I do also explain it.
The next () function that can have any name and by convention has been set to next. It is indirectly related to the operations (PUT, GET, DELETE, ...) that are generally performed on the same URI resource for example / 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 ()...)
Now if you look at app.get, app.put and app.delete use the same uri (/ user /: id), the only thing that differentiates them is their implementation. When the request is made (req) express puts the req first in app.get, if any validation you created because that request is not for that controller fails, it passes the req to app.put which is next route in te file and so on. As seen in the example below.
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()
})
The problem lies, that in the end you end up passing the req to all the controllers hoping that there is one that does what you want, through the validation of the req. In the end all controllers end up receiving something that is not for them :(.
So, how to avoid the problem of next ()?
The answer is really simple.
1-there should only be one uri to identify a resource
http://IpServidor/colection/:resource/colection/:resource if your URI is longer than that, you should consider creating a new uri
Example http://IpServidor/users/pepe/contacts/contacto1
2-All operations on this resource must be done respecting the idempotence of the verbs http (get, post, put, delete, ...) so the call to a URI really only has one way of calling
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
More info [https://docs.microsoft.com/es-es/azure/architecture/best-practices/api-design#organize-the-api-around-resources][1]
Let's see the code! The concrete implementation that makes us avoid the use of next ()!
In the 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 );
In the 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;
Now the usersRoute.js file does what a file called usersRoute is expected to do, which is to manage the routes of the 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 this way you avoid the use of next, you decouple the code, you gain in performance, you develop SOLID, you leave the door open for a possible migration to microservices and above all, it is easy to read by a programmer.