Najlepiej w ogóle go nie używać! Wyjaśniam i to też wyjaśniam.
Funkcja next (), która może mieć dowolną nazwę i zgodnie z konwencją, została ustawiona na next. Jest to pośrednio związane z operacjami (PUT, GET, DELETE, ...), które są zwykle wykonywane na tym samym zasobie URI, na przykład/ 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 ()...)
Teraz, jeśli spojrzysz na app.get, app.put i app.delete używają tego samego uri (/ user /: id), jedyną rzeczą, która je odróżnia, jest ich implementacja. Gdy żądanie jest wysyłane (req) express umieszcza żądanie jako pierwsze w app.get, jeśli jakakolwiek walidacja utworzona, ponieważ to żądanie nie jest dla tego kontrolera nie powiedzie się, przekazuje żądanie do app.put, który jest następną trasą w pliku te, i tak na. Jak widać na poniższym przykładzie.
app.get('/user/:id', function (req,res,next){
if(req.method === 'GET')
else
return next()
})
app.put('/user/:id', function (req,res,next){
if(req.method === 'PUT')
else
return next()
})
Problem polega na tym, że w końcu przekazujesz żądanie wszystkim kontrolerom z nadzieją, że istnieje taki, który robi to, co chcesz, poprzez walidację żądania. W końcu wszyscy kontrolerzy otrzymują coś, co nie jest dla nich :(.
Jak więc uniknąć problemu next () ?
Odpowiedź jest naprawdę prosta.
1- powinien istnieć tylko jeden identyfikator URI do identyfikacji zasobu
http: // IpServidor / colection /: resource / colection /: resource jeśli twój URI jest dłuższy, powinieneś rozważyć utworzenie nowego URI
Przykład http: // IpServidor / users / pepe / kontakt / contacto1
2-Wszystkie operacje na tym zasobie muszą być wykonywane z poszanowaniem idempotencji czasowników http (get, post, put, delete, ...), więc wywołanie URI ma naprawdę tylko jeden sposób wywołania
POST http:
GET http:
PUT http:
DELETE http:
Więcej informacji [ https://docs.microsoft.com/es-es/azure/architecture/best-practices/api-design#organize-the-api-around-resources][1]
Zobaczmy kod! Konkretna implementacja, dzięki której unikamy użycia next ()!
W pliku index.js
const express = require('express');
const app = express();
const usersRoute = require('./src/route/usersRoute.js');
app.use('/users', usersRoute );
W pliku 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':
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;
Teraz plik usersRoute.js robi to, czego oczekuje się od pliku o nazwie usersRoute, czyli zarządzania trasami URI / users /
// plik 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;
W ten sposób unikasz użycia next, odprzęgasz kod, zyskujesz na wydajności, rozwijasz SOLID, zostawiasz otwarte drzwi na ewentualną migrację do mikroserwisów i przede wszystkim jest łatwy do odczytania przez programistę.
res.redirect('/')
miałaby miejscereturn res.redirect('/')
w przypadku tego typu sytuacji? Może po prostu lepiej jest zawsze pisać return przed instrukcjami res, aby uniknąć błędów w ustawianiu nagłówków po ich wysłaniu?