94 lines
3.0 KiB
JavaScript
94 lines
3.0 KiB
JavaScript
const ApplicationError = require('../utils/application-error');
|
|
const validMethod = {
|
|
get: 'get',
|
|
post: 'post',
|
|
delete: 'delete',
|
|
patch: 'patch',
|
|
put: 'put'
|
|
};
|
|
|
|
/**
|
|
* A class that represents a controller for processing HTTP routes.
|
|
*/
|
|
class Controller {
|
|
/**
|
|
* Creates a new instance of the Controller class.
|
|
*
|
|
* @param {Object} options Options for the controller.
|
|
* @param {string} options.method HTTP method (for example, 'get', 'post', 'delete', 'patch', 'put').
|
|
* @param {string} options.path The route path (URL).
|
|
* @param {function} options.handler The request handler that will be called when the route is accessed.
|
|
* @param {Joi.Schema} options.validationSchema Validation scheme for validating input data.
|
|
* @param {function[]} options.middlewares Middleware to be called before the handler.
|
|
*/
|
|
constructor({ method, path, handler, validationSchema, middlewares }) {
|
|
if (!validMethod[method] || !path || !handler) {
|
|
console.error(`Controller misconfiguration. Method: ${method}, path: ${path}, handler exists: ${!!handler}`);
|
|
process.exit(-1);
|
|
}
|
|
this.method = method;
|
|
this.path = path;
|
|
this.handler = handler;
|
|
this.validationSchema = validationSchema;
|
|
this.middlewares = middlewares;
|
|
}
|
|
|
|
/**
|
|
* Validates input data according to the validation scheme.
|
|
*
|
|
* @param {Express.Request} req The Express request object.
|
|
* @param {Express.Response} res The Express response object.
|
|
* @throws {ApplicationError.JsonValidation} If the data does not match the validation scheme.
|
|
*/
|
|
async validate(req, res) {
|
|
if (!this.validationSchema) {
|
|
return;
|
|
}
|
|
const objectToValidate = this.method === 'get' ? req.query : req.body;
|
|
try {
|
|
const value = await this.validationSchema.validateAsync(objectToValidate, {stripUnknown: true});
|
|
if (this.method === 'get') {
|
|
req.query = value;
|
|
} else {
|
|
req.body = value;
|
|
}
|
|
} catch (e) {
|
|
const message = e.details.map(i => i.message).join(',');
|
|
throw ApplicationError.JsonValidation(message);
|
|
}
|
|
}
|
|
/**
|
|
* Performs HTTP request processing.
|
|
*
|
|
* @param {Express.Request} req The Express request object.
|
|
* @param {Express.Response} res The Express response object.
|
|
* @param {function} next Function for further processing of the request.
|
|
*/
|
|
async run(req, res, next) {
|
|
try {
|
|
const handlerResult = await this.handler(req, res, next);
|
|
if (!res.headersSent) {
|
|
return res.status(200).json({ success: true, statusCode: 200, data: handlerResult });
|
|
}
|
|
} catch (e) {
|
|
next(e);
|
|
}
|
|
}
|
|
/**
|
|
* Registers the controller with the Express router.
|
|
* @param {Express.Router} router The Express router in which the controller will be registered.
|
|
*/
|
|
register(router) {
|
|
const self = this;
|
|
const handle = async function (req, res, next) {
|
|
return await self.run(req, res, next);
|
|
};
|
|
this.middlewares.forEach(middleware => {
|
|
router[this.method](this.path, middleware) ;
|
|
});
|
|
router[this.method](this.path, handle);
|
|
}
|
|
}
|
|
|
|
module.exports = Controller;
|