En mi aplicación Express implemento rutas en route.ts:
var Router = express.Router(); Router.route('/models/:modelId') .get(function (req, res) { service.setParameter(req) service.get(req,res) }); Router.route('/models/:modelId') .post(function (req, res) { service.setParameter(req) service.post(req,res) });Y express.ts:
export const App = express() App.use(express.json()) App.use(express.urlencoded({ extended: true })) App.use(helmet()) App.use('/', Router)En cada llamada del enrutador, me gustaría ejecutar un fragmento de código service.setParameter (req) que obtiene un parámetro particular de 'params', pero no quiero agregar explícitamente a cada método de enrutador.
Intenté agregarlo como middleware antes y después del enrutador
App.use('/', Router) App.use(function(req, res, next){ service.setParameter(req) next() })Pero si lo defino antes del enrutador, entonces la ruta aún no se ha configurado y no obtengo el parámetro que quiero, y si lo defino después, entonces el middleware no se ejecuta.
¿Cómo se puede ejecutar service.setParameter(req) de forma genérica para que se aplique a todas las rutas?
Debe colocar su middleware personalizado entre la ruta de contexto y su enrutador dentro app.use(..) :
const router = express.Router(); router.post('/', (req, res) => { service.post(req,res); }); router.get('/', (req, res) => { service.get(req,res) }); app.use('/models', (req, res, next) => { service.setParameter(req); next(); }, router); Con el código anterior, el middleware se ejecutará para todas las solicitudes a '/models' .
Puede usar app.use(async (req,res,next) => {...}) para declarar un middleware que se ejecuta en todas las solicitudes, si desea que este middleware se llame primero, debe declararse antes de sus rutas, el middleware debe llamar a next() para continuar con el flujo de ejecución, si desea que lo llamen al final de su solicitud, debe ponerlo al final de sus declaraciones pero antes del error middleware, en ese enfoque, cada ruta debe llamar a next() al final de su función.
Primer enfoque
const express = require('express'); const app = express(); const router = express.Router(); router.post('/', async (req, res) => { await service.post(req,res); }); router.get('/', async (req, res) => { await service.get(req,res) }); app.use((req,res,next) => { console.log("always called"); next(); }); app.use('/',router);Segundo enfoque
const express = require('express'); const app = express(); const router = express.Router(); router.post('/', async (req, res, next) => { await service.post(req,res); next(); }); router.get('/', async (req, res, next) => { await service.get(req,res); next(); }); app.use('/',router); app.use((req,res) => { console.log("always called"); });En el archivo express.ts , puede agregar un middleware que lo haría antes de montar el enrutador, y luego continuar con next() . Puedes hacerlo así:
App.use('/*', (req, res, next) => { service.setParameter(req); next(); }); App.use('/', Router)Gracias por todas las respuestas, me ayudaron a comprender mejor cómo funciona el enrutamiento en Express.
Encontré otra solución, que creo que funciona mejor en mi caso, usando el método Router.all():
const setRequest = function(req, res, next){ logger.setRequest(request) next() } Router.route('/models/:model_id') .all(setRequest) .get(function (req, res) {service.execute()}) .put(function (req, res) {service.execute()})