mirror of
https://github.com/sergeyyarkov/node-docker-example.git
synced 2026-10-11 18:29:34 +03:00
feat: added middlewares
This commit is contained in:
parent
93c72e36a8
commit
ac9248bf7f
12
helpers/string.js
Normal file
12
helpers/string.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
class StringHelper {
|
||||||
|
/**
|
||||||
|
* Delete the trailing slash from url
|
||||||
|
*
|
||||||
|
* @param {string} url
|
||||||
|
*/
|
||||||
|
static delTrailingSlash(url) {
|
||||||
|
return url.slice(-1) === '/' ? url.slice(0, -1) : url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default StringHelper;
|
||||||
13
middlewares.js
Normal file
13
middlewares.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import http from 'node:http';
|
||||||
|
import Response from './response.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This middleware just prints text to console
|
||||||
|
*
|
||||||
|
* @param {http.ClientRequest} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @param {function} next
|
||||||
|
*/
|
||||||
|
export const helloMiddleware = (req, res) => {
|
||||||
|
console.log('[LOG]: Hello from `helloMiddleware` function');
|
||||||
|
};
|
||||||
@ -9,6 +9,11 @@ import {
|
|||||||
getArticlesHandler,
|
getArticlesHandler,
|
||||||
} from '../handlers.js';
|
} from '../handlers.js';
|
||||||
|
|
||||||
router.define('GET', '/api/articles', getArticlesHandler);
|
/**
|
||||||
router.define('GET', '/api/article/:id', getArticleHandler);
|
* Middlewares
|
||||||
router.define('POST', '/api/article', createArticleHandler);
|
*/
|
||||||
|
import { helloMiddleware } from '../middlewares.js';
|
||||||
|
|
||||||
|
router.get('/api/articles', getArticlesHandler).middleware([helloMiddleware]);
|
||||||
|
router.get('/api/article/:id', getArticleHandler).middleware([helloMiddleware]);
|
||||||
|
router.post('/api/article', createArticleHandler);
|
||||||
|
|||||||
107
router.js
107
router.js
@ -1,5 +1,6 @@
|
|||||||
import http from 'node:http';
|
import http from 'node:http';
|
||||||
import { pathToRegexp } from 'path-to-regexp';
|
import { pathToRegexp } from 'path-to-regexp';
|
||||||
|
import StringHelper from './helpers/string.js';
|
||||||
|
|
||||||
class Router {
|
class Router {
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -17,24 +18,28 @@ class Router {
|
|||||||
* @returns {boolean} Is route has been handled
|
* @returns {boolean} Is route has been handled
|
||||||
*/
|
*/
|
||||||
call(req, res) {
|
call(req, res) {
|
||||||
const mask = `${req.method}:${req.url}`;
|
const mask = `${req.method}:${StringHelper.delTrailingSlash(req.url)}`;
|
||||||
|
|
||||||
/**
|
|
||||||
* Find the exact route
|
|
||||||
*/
|
|
||||||
if (this.routes.hasOwnProperty(mask)) {
|
|
||||||
this.routes[mask].handler(req, res);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find route by regular expression
|
|
||||||
*/
|
|
||||||
const keys = Object.keys(this.routes);
|
const keys = Object.keys(this.routes);
|
||||||
let i = keys.length;
|
let i = keys.length;
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
const route = this.routes[keys[i]];
|
let route = this.routes[mask];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find exact route
|
||||||
|
*/
|
||||||
|
if (this.routes.hasOwnProperty(mask)) {
|
||||||
|
this.#middlewares(route, req, res);
|
||||||
|
route.handler(req, res);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Route url is not exact */
|
||||||
|
route = this.routes[keys[i]];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find route by regular expression
|
||||||
|
*/
|
||||||
if (!route.options.exact && route.options.regexp !== undefined) {
|
if (!route.options.exact && route.options.regexp !== undefined) {
|
||||||
const match = req.url.match(route.options.regexp);
|
const match = req.url.match(route.options.regexp);
|
||||||
if (match && keys[i].includes(req.method)) {
|
if (match && keys[i].includes(req.method)) {
|
||||||
@ -44,6 +49,7 @@ class Router {
|
|||||||
req.params[param.name] = match[1];
|
req.params[param.name] = match[1];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
this.#middlewares(route, req, res);
|
||||||
route.handler(req, res);
|
route.handler(req, res);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -53,29 +59,82 @@ class Router {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function will execute every middleware of a route
|
||||||
|
*
|
||||||
|
* @param {*} route
|
||||||
|
* @param {http.ClientRequest} req
|
||||||
|
* @param {Response} res
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
#middlewares(route, req, res) {
|
||||||
|
if (!route || !route.middlewares || !Array.isArray(route.middleware)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const middlewares = route.middlewares.flat();
|
||||||
|
if (middlewares.length !== 0) {
|
||||||
|
for (const middleware of middlewares) {
|
||||||
|
middleware(req, res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add more routes to router store
|
* Add more routes to router store
|
||||||
*
|
*
|
||||||
* @param {string} url
|
* @param {string} method HTTP Method
|
||||||
* @param {function} handler
|
* @param {string} url Route url
|
||||||
* @param {boolean} exact
|
* @param {function} handler Route handler function
|
||||||
*/
|
*/
|
||||||
define(
|
define(method = 'GET', url, handler) {
|
||||||
method = 'GET',
|
const mask = `${method}:${StringHelper.delTrailingSlash(url)}`;
|
||||||
url,
|
const options = { exact: true, regexp: undefined, params: undefined };
|
||||||
handler,
|
|
||||||
options = { exact: true, regexp: undefined, params: undefined }
|
|
||||||
) {
|
|
||||||
if (url.includes(':')) {
|
if (url.includes(':')) {
|
||||||
options.params = [];
|
options.params = [];
|
||||||
options.exact = false;
|
options.exact = false;
|
||||||
options.regexp = pathToRegexp(url, options.params);
|
options.regexp = pathToRegexp(url, options.params);
|
||||||
}
|
}
|
||||||
this.routes[`${method}:${url}`] = {
|
|
||||||
|
this.routes[mask] = {
|
||||||
method,
|
method,
|
||||||
handler,
|
handler,
|
||||||
options,
|
options,
|
||||||
|
middlewares: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Store the list of middlewares for each router
|
||||||
|
*
|
||||||
|
* @param {function | [function]} middleware
|
||||||
|
*/
|
||||||
|
middleware: (middleware) => {
|
||||||
|
middleware = Array.isArray(middleware) ? middleware : [middleware];
|
||||||
|
this.routes[mask].middlewares.push(middleware);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET Method route
|
||||||
|
*
|
||||||
|
* @param {string} url
|
||||||
|
* @param {function} handler
|
||||||
|
*/
|
||||||
|
get(url, handler) {
|
||||||
|
return this.define('GET', url, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST Method route
|
||||||
|
*
|
||||||
|
* @param {string} url
|
||||||
|
* @param {function} handler
|
||||||
|
*/
|
||||||
|
post(url, handler) {
|
||||||
|
return this.define('POST', url, handler);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user