feat: added support for async middlewares

This commit is contained in:
Sergey Yarkov 2022-03-16 20:56:05 +03:00
parent ac9248bf7f
commit c00ec6779a
3 changed files with 33 additions and 16 deletions

View File

@ -2,12 +2,18 @@ import http from 'node:http';
import Response from './response.js'; import Response from './response.js';
/** /**
* This middleware just prints text to console * This middleware waits for a few milliseconds
* *
* @param {http.ClientRequest} req * @param {http.ClientRequest} req
* @param {Response} res * @param {Response} res
* @param {function} next * @param {function} next
*/ */
export const helloMiddleware = (req, res) => { export const waitMiddleware = async (req, res) => {
console.log('[LOG]: Hello from `helloMiddleware` function'); const wait = (ms = 1000) => {
return new Promise((res) => {
setTimeout(() => res(ms), ms);
});
};
await wait(50);
}; };

View File

@ -12,8 +12,8 @@ import {
/** /**
* Middlewares * Middlewares
*/ */
import { helloMiddleware } from '../middlewares.js'; import { waitMiddleware } from '../middlewares.js';
router.get('/api/articles', getArticlesHandler).middleware([helloMiddleware]); router.get('/api/articles', getArticlesHandler).middleware([waitMiddleware]);
router.get('/api/article/:id', getArticleHandler).middleware([helloMiddleware]); router.get('/api/articles/:id', getArticleHandler).middleware([waitMiddleware]);
router.post('/api/article', createArticleHandler); router.post('/api/article', createArticleHandler);

View File

@ -1,7 +1,18 @@
import http from 'node:http'; import http from 'node:http';
import util from 'node:util';
import { pathToRegexp } from 'path-to-regexp'; import { pathToRegexp } from 'path-to-regexp';
import StringHelper from './helpers/string.js'; import StringHelper from './helpers/string.js';
/**
* Single route type
* @typedef {{ method: string, handler: function, options: RouteOptions, middlewares: Array<function> }} Route
*/
/**
* Route options type
* @typedef {{ params: Array, exact: boolean, regexp: RegExp }} RouteOptions
*/
class Router { class Router {
constructor() { constructor() {
/** /**
@ -29,8 +40,7 @@ class Router {
* Find exact route * Find exact route
*/ */
if (this.routes.hasOwnProperty(mask)) { if (this.routes.hasOwnProperty(mask)) {
this.#middlewares(route, req, res); this.#middlewares(route, req, res).then(() => route.handler(req, res));
route.handler(req, res);
return true; return true;
} }
@ -49,8 +59,9 @@ class Router {
req.params[param.name] = match[1]; req.params[param.name] = match[1];
}); });
} }
this.#middlewares(route, req, res); this.#middlewares(route, req, res).then(() =>
route.handler(req, res); route.handler(req, res)
);
return true; return true;
} }
} }
@ -62,20 +73,20 @@ class Router {
/** /**
* This function will execute every middleware of a route * This function will execute every middleware of a route
* *
* @param {*} route * @param {Route} route Route
* @param {http.ClientRequest} req * @param {http.ClientRequest} req HTTP Request
* @param {Response} res * @param {Response} res HTTP Response
* @returns * @returns
*/ */
#middlewares(route, req, res) { async #middlewares(route, req, res) {
if (!route || !route.middlewares || !Array.isArray(route.middleware)) { if (!route || !route.middlewares || !Array.isArray(route.middlewares)) {
return; return;
} }
const middlewares = route.middlewares.flat(); const middlewares = route.middlewares.flat();
if (middlewares.length !== 0) { if (middlewares.length !== 0) {
for (const middleware of middlewares) { for (const middleware of middlewares) {
middleware(req, res); await middleware(req, res);
} }
} }
} }