expressed-example-app 2.0.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,22 +1,26 @@
1
1
  # Express-Router-BDS Example Application
2
2
 
3
- This is a sample Express.js application demonstrating the usage of the `express-router-bds` routing system with custom hooks and advanced features.
3
+ This is a sample Express.js application demonstrating the usage of the `express-router-bds` routing system with custom hooks, advanced features, and integrated queue system.
4
4
 
5
5
  ## Overview
6
6
 
7
7
  This example application showcases:
8
8
 
9
- - High-performance routing with `express-router-bDS`
9
+ - High-performance routing with `express-router-bds`
10
10
  - JSON-based route configuration
11
11
  - Custom hook system implementation
12
12
  - Parameterized route handling
13
13
  - Directory-based route loading
14
+ - Integrated queue system with `express-queued`
15
+ - Declarative route definitions in separate JSON files
14
16
 
15
17
  ## Features
16
18
 
17
19
  - **Modular Route Configuration**: Routes defined in JSON files for easy maintenance
18
20
  - **Custom Hooks**: Comprehensive hook system with `pre_route_load`, `post_route_load`, `before_route_handler`, `after_route_handler`, `route_handler_error`, and more
19
21
  - **Parameterized Routes**: Support for dynamic routes like `/users/:id` and `/products/:category/:id`
22
+ - **Integrated Queue System**: Background task processing with `express-queued`
23
+ - **Declarative Routes**: Separate route files for different functionalities
20
24
  - **Extensible Architecture**: Easy to extend with custom middleware and hooks
21
25
 
22
26
  ## Project Structure
@@ -24,26 +28,54 @@ This example application showcases:
24
28
  ```
25
29
  express-app/
26
30
  ├── app.js # Main application entry point
31
+ ├── queue-system.js # Queue system integration
27
32
  ├── hooks-config.js # Base hook configurations
28
33
  ├── hooks-personalizados.js # Custom hook implementations
29
34
  ├── controllers/
30
- │ ├── mainController.js # Home and init route handlers
35
+ │ ├── mainController.js # Home, init and queue route handlers
31
36
  │ ├── productController.js # Product route handlers
32
37
  │ └── userController.js # User route handlers
33
38
  ├── routes/
34
- └── main-routes.json # Route definitions in JSON format
39
+ ├── main-routes.json # Main route definitions in JSON format
40
+ │ └── queue-routes.json # Queue-related route definitions
35
41
  └── node_modules/
36
- └── express-router-bds/ # Custom routing system
42
+ ├── express-router-bds/ # Custom routing system
43
+ └── express-queued/ # Queue system
37
44
  ```
38
45
 
39
46
  ## Available Endpoints
40
47
 
48
+ ### Main Endpoints
41
49
  - `GET /` - Home page with welcome message
42
50
  - `GET /init` - Initialization endpoint
43
51
  - `GET /users/:id` - Get user by ID
44
52
  - `GET /products/:category/:id` - Get product by category and ID
45
53
  - `GET /test-hook` - Test endpoint for hook demonstration
46
54
 
55
+ ### Queue System Endpoints
56
+ - `GET /queue-status` - Get the status of the queue system
57
+ - `GET /start-queues` - Start the queue system
58
+ - `GET /stop-queues` - Stop the queue system
59
+ - `POST /process-user` - Add a user processing task to the queue
60
+ - `POST /process-product` - Add a product processing task to the queue
61
+ - `POST /send-email` - Add an email sending task to the queue
62
+
63
+ ## Queue System
64
+
65
+ The application integrates `express-queued` for background task processing:
66
+
67
+ - **Multiple Queues**: Dedicated queues for different types of tasks
68
+ - **Configurable Concurrency**: Control how many tasks execute simultaneously per queue
69
+ - **Retry System**: Automatic failure handling with configurable retries
70
+ - **Priority Management**: Assign priorities to tasks
71
+ - **Hooks Integration**: Customize processing with hooks
72
+
73
+ ### Queue Types
74
+ - `procesamiento-general` - General processing tasks
75
+ - `envio-correos` - Email sending tasks
76
+ - `procesamiento-usuarios` - User processing tasks
77
+ - `procesamiento-productos` - Product processing tasks
78
+
47
79
  ## Hook System
48
80
 
49
81
  The application demonstrates several types of hooks:
@@ -74,7 +106,7 @@ The application will be available at `http://localhost:3000`
74
106
 
75
107
  ## Testing
76
108
 
77
- Test the endpoints:
109
+ Test the main endpoints:
78
110
 
79
111
  ```bash
80
112
  curl http://localhost:3000
@@ -82,6 +114,23 @@ curl http://localhost:3000/users/123
82
114
  curl http://localhost:3000/products/electronics/456
83
115
  ```
84
116
 
117
+ Test the queue system:
118
+
119
+ ```bash
120
+ # Check queue status
121
+ curl http://localhost:3000/queue-status
122
+
123
+ # Add a user processing task
124
+ curl -X POST http://localhost:3000/process-user \
125
+ -H "Content-Type: application/json" \
126
+ -d '{"userId": "123", "name": "John Doe", "email": "john@example.com"}'
127
+
128
+ # Add an email sending task
129
+ curl -X POST http://localhost:3000/send-email \
130
+ -H "Content-Type: application/json" \
131
+ -d '{"to": "test@example.com", "subject": "Test", "content": "Test content"}'
132
+ ```
133
+
85
134
  ## License
86
135
 
87
136
  This project is part of the `express-router-bds` ecosystem and follows the same licensing terms.
package/app.js CHANGED
@@ -3,6 +3,7 @@ const ExpressRouterIntegration = require('express-router-bds');
3
3
  const RouteDirectoryLoader = require('express-router-bds/RouteDirectoryLoader');
4
4
  const AppHooks = require('./hooks-config');
5
5
  const HooksPersonalizados = require('./hooks-personalizados');
6
+ const QueueSystem = require('./queue-system');
6
7
 
7
8
  const app = express();
8
9
  const PORT = process.env.PORT || 3000;
@@ -10,16 +11,29 @@ const PORT = process.env.PORT || 3000;
10
11
  // Crear instancia del router
11
12
  const routerIntegration = new ExpressRouterIntegration();
12
13
 
14
+ // Crear instancia del sistema de colas
15
+ const queueSystem = new QueueSystem();
16
+
13
17
  // Inicializar hooks y filtros
14
18
  const appHooks = new AppHooks(app, routerIntegration.getHooks());
15
19
 
16
20
  // Inicializar hooks personalizados
17
21
  const hooksPersonalizados = new HooksPersonalizados(routerIntegration);
18
22
 
19
-
20
23
  // Cargar rutas desde directorio
21
24
  const routeDirectoryLoader = new RouteDirectoryLoader();
22
25
 
26
+ // Middleware para parsear JSON
27
+ app.use(express.json());
28
+
29
+ // Middleware para inyectar el sistema de colas en las solicitudes
30
+ app.use(queueSystem.getInstance().queueMiddleware());
31
+
32
+ // Middleware para inyectar el sistema de rutas en las solicitudes
33
+ app.use((req, res, next) => {
34
+ req.routerIntegration = routerIntegration;
35
+ next();
36
+ });
23
37
 
24
38
  routerIntegration.addHook('route_matched', (matchedRoute, req, res) => {
25
39
  console.log(`Ruta encontrada: ${matchedRoute.route.path}`);
@@ -41,6 +55,20 @@ routeDirectoryLoader.loadRoutesFromDirectory(routerIntegration, './routes')
41
55
  console.error('Error cargando rutas desde directorio:', error.message);
42
56
  });
43
57
 
58
+ // Cargar rutas específicas de colas
59
+ const RouteLoader = require('express-router-bds/RouteLoader');
60
+ const queueRouteLoader = new RouteLoader();
61
+ queueRouteLoader.loadRoutes(routerIntegration, './routes/queue-routes.json')
62
+ .then(queueRoutes => {
63
+ console.log(`${queueRoutes.length} rutas de colas cargadas`);
64
+ queueRoutes.forEach(route => {
65
+ console.log(`Ruta de cola cargada: ${route.method} ${route.path}`);
66
+ });
67
+ })
68
+ .catch(error => {
69
+ console.error('Error cargando rutas de colas:', error.message);
70
+ });
71
+
44
72
  // Aplicar el router a la aplicación Express
45
73
  routerIntegration.applyToApp(app);
46
74
 
@@ -49,6 +77,72 @@ app.use((req, res) => {
49
77
  res.status(404).json({ error: 'Ruta no encontrada' });
50
78
  });
51
79
 
80
+ // Ruta para obtener el estado del sistema de colas
81
+ app.get('/queue-status', (req, res) => {
82
+ const status = req.getQueueStatus();
83
+ res.json(status);
84
+ });
85
+
86
+ // Ruta para iniciar el sistema de colas
87
+ app.get('/start-queues', (req, res) => {
88
+ queueSystem.start();
89
+ res.json({ message: 'Sistema de colas iniciado' });
90
+ });
91
+
92
+ // Ruta para detener el sistema de colas
93
+ app.get('/stop-queues', (req, res) => {
94
+ queueSystem.stop();
95
+ res.json({ message: 'Sistema de colas detenido' });
96
+ });
97
+
98
+ // Ruta para procesar un usuario en cola
99
+ app.post('/process-user', (req, res) => {
100
+ const { userId, name, email } = req.body;
101
+
102
+ if (!userId) {
103
+ return res.status(400).json({ error: 'userId es requerido' });
104
+ }
105
+
106
+ const taskId = queueSystem.addUserProcessingTask({ userId, name, email });
107
+
108
+ res.json({
109
+ message: 'Tarea de procesamiento de usuario agregada a la cola',
110
+ taskId
111
+ });
112
+ });
113
+
114
+ // Ruta para procesar un producto en cola
115
+ app.post('/process-product', (req, res) => {
116
+ const { productId, name, price } = req.body;
117
+
118
+ if (!productId) {
119
+ return res.status(400).json({ error: 'productId es requerido' });
120
+ }
121
+
122
+ const taskId = queueSystem.addProductProcessingTask({ productId, name, price });
123
+
124
+ res.json({
125
+ message: 'Tarea de procesamiento de producto agregada a la cola',
126
+ taskId
127
+ });
128
+ });
129
+
130
+ // Ruta para enviar un correo en cola
131
+ app.post('/send-email', (req, res) => {
132
+ const { to, subject, content } = req.body;
133
+
134
+ if (!to) {
135
+ return res.status(400).json({ error: 'to es requerido' });
136
+ }
137
+
138
+ const taskId = queueSystem.addEmailSendingTask({ to, subject, content });
139
+
140
+ res.json({
141
+ message: 'Tarea de envío de correo agregada a la cola',
142
+ taskId
143
+ });
144
+ });
145
+
52
146
  // Iniciar el servidor
53
147
  app.listen(PORT, () => {
54
148
  console.log(`Servidor corriendo en el puerto ${PORT}`);
@@ -57,6 +151,17 @@ app.listen(PORT, () => {
57
151
  console.log('- GET /init');
58
152
  console.log('- GET /users/:id');
59
153
  console.log('- GET /products/:category/:id');
154
+ console.log('- GET /test-hook');
155
+ console.log('- GET /queue-status');
156
+ console.log('- GET /start-queues');
157
+ console.log('- GET /stop-queues');
158
+ console.log('- POST /process-user');
159
+ console.log('- POST /process-product');
160
+ console.log('- POST /send-email');
161
+
162
+ // Iniciar el sistema de colas
163
+ queueSystem.start();
164
+ console.log('Sistema de colas iniciado');
60
165
  });
61
166
 
62
167
  module.exports = app;
@@ -24,11 +24,73 @@ class MainController {
24
24
  * @param {Object} res - Objeto de respuesta
25
25
  */
26
26
  init(req, res) {
27
- res.json({
27
+ res.json({
28
28
  message: 'Aplicación inicializada correctamente con Router-BDS',
29
29
  status: 'success'
30
30
  });
31
31
  }
32
+
33
+ /**
34
+ * Obtiene el estado del sistema de colas
35
+ * @param {Object} req - Objeto de solicitud
36
+ * @param {Object} res - Objeto de respuesta
37
+ */
38
+ getQueueStatus(req, res) {
39
+ const status = req.getQueueStatus();
40
+ res.json(status);
41
+ }
42
+
43
+ /**
44
+ * Inicia el sistema de colas
45
+ * @param {Object} req - Objeto de solicitud
46
+ * @param {Object} res - Objeto de respuesta
47
+ */
48
+ startQueues(req, res) {
49
+ req.queueSystem.start();
50
+ res.json({ message: 'Sistema de colas iniciado' });
51
+ }
52
+
53
+ /**
54
+ * Detiene el sistema de colas
55
+ * @param {Object} req - Objeto de solicitud
56
+ * @param {Object} res - Objeto de respuesta
57
+ */
58
+ stopQueues(req, res) {
59
+ req.queueSystem.stop();
60
+ res.json({ message: 'Sistema de colas detenido' });
61
+ }
62
+
63
+ /**
64
+ * Agrega una tarea de envío de correo a la cola
65
+ * @param {Object} req - Objeto de solicitud
66
+ * @param {Object} res - Objeto de respuesta
67
+ */
68
+ sendEmailInQueue(req, res) {
69
+ const { to, subject, content } = req.body;
70
+
71
+ if (!to) {
72
+ return res.status(400).json({ error: 'to es requerido' });
73
+ }
74
+
75
+ const taskId = req.addTask('envio-correos', async (data, taskObj) => {
76
+ console.log(`[ENVIO-CORREO] Enviando correo a: ${data.to}`);
77
+
78
+ // Simular envío de correo (con 10% de probabilidad de fallo)
79
+ await new Promise(resolve => setTimeout(resolve, 1000));
80
+
81
+ if (Math.random() < 0.1) {
82
+ throw new Error(`Fallo al enviar correo a: ${data.to}`);
83
+ }
84
+
85
+ console.log(`[ENVIO-CORREO] Correo enviado exitosamente a: ${data.to}`);
86
+ return `Correo enviado a ${data.to} exitosamente`;
87
+ }, { to, subject, content });
88
+
89
+ res.json({
90
+ message: 'Tarea de envío de correo agregada a la cola',
91
+ taskId
92
+ });
93
+ }
32
94
  }
33
95
 
34
96
  module.exports = new MainController();
@@ -10,13 +10,41 @@ class ProductController {
10
10
  getProduct(req, res) {
11
11
  const category = req.params.category;
12
12
  const productId = req.params.id;
13
- res.json({
13
+ res.json({
14
14
  message: `Obteniendo producto de la categoría "${category}" con ID: ${productId}`,
15
15
  category: category,
16
16
  productId: productId,
17
17
  timestamp: new Date().toISOString()
18
18
  });
19
19
  }
20
+
21
+ /**
22
+ * Procesa un producto en cola
23
+ * @param {Object} req - Objeto de solicitud
24
+ * @param {Object} res - Objeto de respuesta
25
+ */
26
+ processProductInQueue(req, res) {
27
+ const { productId, name, price } = req.body;
28
+
29
+ if (!productId) {
30
+ return res.status(400).json({ error: 'productId es requerido' });
31
+ }
32
+
33
+ const taskId = req.addTask('procesamiento-productos', async (data, taskObj) => {
34
+ console.log(`[PROCESAMIENTO-PRODUCTO] Procesando producto:`, data.productId || data.id);
35
+
36
+ // Simular procesamiento
37
+ await new Promise(resolve => setTimeout(resolve, 1500));
38
+
39
+ console.log(`[PROCESAMIENTO-PRODUCTO] Producto procesado exitosamente:`, data.productId || data.id);
40
+ return `Producto ${data.productId || data.id} procesado exitosamente`;
41
+ }, { productId, name, price });
42
+
43
+ res.json({
44
+ message: 'Tarea de procesamiento de producto agregada a la cola',
45
+ taskId
46
+ });
47
+ }
20
48
  }
21
49
 
22
50
  module.exports = new ProductController();
@@ -9,12 +9,40 @@ class UserController {
9
9
  */
10
10
  getUser(req, res) {
11
11
  const userId = req.params.id;
12
- res.json({
12
+ res.json({
13
13
  message: `Obteniendo información del usuario con ID: ${userId}`,
14
14
  userId: userId,
15
15
  timestamp: new Date().toISOString()
16
16
  });
17
17
  }
18
+
19
+ /**
20
+ * Procesa un usuario en cola
21
+ * @param {Object} req - Objeto de solicitud
22
+ * @param {Object} res - Objeto de respuesta
23
+ */
24
+ processUserInQueue(req, res) {
25
+ const { userId, name, email } = req.body;
26
+
27
+ if (!userId) {
28
+ return res.status(400).json({ error: 'userId es requerido' });
29
+ }
30
+
31
+ const taskId = req.addTask('procesamiento-usuarios', async (data, taskObj) => {
32
+ console.log(`[PROCESAMIENTO-USUARIO] Procesando usuario:`, data.userId || data.id);
33
+
34
+ // Simular procesamiento
35
+ await new Promise(resolve => setTimeout(resolve, 2000));
36
+
37
+ console.log(`[PROCESAMIENTO-USUARIO] Usuario procesado exitosamente:`, data.userId || data.id);
38
+ return `Usuario ${data.userId || data.id} procesado exitosamente`;
39
+ }, { userId, name, email });
40
+
41
+ res.json({
42
+ message: 'Tarea de procesamiento de usuario agregada a la cola',
43
+ taskId
44
+ });
45
+ }
18
46
  }
19
47
 
20
48
  module.exports = new UserController();
package/package.json CHANGED
@@ -1,13 +1,38 @@
1
1
  {
2
2
  "name": "expressed-example-app",
3
- "version": "2.0.0",
4
- "description": "",
3
+ "version": "2.1.0",
4
+ "description": "Advanced Express.js application featuring high-performance routing with custom hooks, declarative route definitions, and integrated queue system for background task processing. Perfect for scalable web applications requiring sophisticated routing and async job handling.",
5
5
  "main": "app.js",
6
6
  "scripts": {
7
7
  "start": "node app.js",
8
8
  "test": "echo \"Error: no test specified\" && exit 1"
9
9
  },
10
- "keywords": ["web express example"],
10
+ "keywords": [
11
+ "express",
12
+ "routing",
13
+ "router",
14
+ "middleware",
15
+ "api",
16
+ "rest",
17
+ "web-framework",
18
+ "backend",
19
+ "server",
20
+ "http",
21
+ "framework",
22
+ "nodejs",
23
+ "javascript",
24
+ "queues",
25
+ "async",
26
+ "asynchronous",
27
+ "tasks",
28
+ "jobs",
29
+ "background-jobs",
30
+ "hooks",
31
+ "extensible",
32
+ "modular",
33
+ "declarative-routing",
34
+ "web express example"
35
+ ],
11
36
  "author": "BDS",
12
37
  "license": "ISC",
13
38
  "dependencies": {
@@ -0,0 +1,128 @@
1
+ // queue-system.js
2
+ // Sistema de colas para la aplicación Express
3
+
4
+ const ExpressQueueIntegration = require('express-queued');
5
+
6
+ class QueueSystem {
7
+ constructor() {
8
+ // Crear instancia del sistema de colas
9
+ this.expressQueue = new ExpressQueueIntegration();
10
+
11
+ // Configurar las colas
12
+ this.setupQueues();
13
+ }
14
+
15
+ setupQueues() {
16
+ // Cola para procesamiento general
17
+ this.expressQueue.createQueue('procesamiento-general', {
18
+ concurrency: 2,
19
+ retryAttempts: 3,
20
+ retryDelay: 1000
21
+ });
22
+
23
+ // Cola para envío de correos
24
+ this.expressQueue.createQueue('envio-correos', {
25
+ concurrency: 1,
26
+ retryAttempts: 5,
27
+ retryDelay: 2000
28
+ });
29
+
30
+ // Cola para procesamiento de usuarios
31
+ this.expressQueue.createQueue('procesamiento-usuarios', {
32
+ concurrency: 3,
33
+ retryAttempts: 2,
34
+ retryDelay: 1500
35
+ });
36
+
37
+ // Cola para procesamiento de productos
38
+ this.expressQueue.createQueue('procesamiento-productos', {
39
+ concurrency: 2,
40
+ retryAttempts: 3,
41
+ retryDelay: 1000
42
+ });
43
+ }
44
+
45
+ // Método para obtener la instancia del sistema de colas
46
+ getInstance() {
47
+ return this.expressQueue;
48
+ }
49
+
50
+ // Método para iniciar el sistema de colas
51
+ start() {
52
+ this.expressQueue.start();
53
+ }
54
+
55
+ // Método para detener el sistema de colas
56
+ stop() {
57
+ this.expressQueue.stop();
58
+ }
59
+
60
+ // Ejemplo de tarea para procesamiento de usuarios
61
+ addUserProcessingTask(userData) {
62
+ return this.expressQueue.addTask(
63
+ 'procesamiento-usuarios',
64
+ this.processUser.bind(this),
65
+ userData,
66
+ 0 // Prioridad alta
67
+ );
68
+ }
69
+
70
+ // Ejemplo de tarea para procesamiento de productos
71
+ addProductProcessingTask(productData) {
72
+ return this.expressQueue.addTask(
73
+ 'procesamiento-productos',
74
+ this.processProduct.bind(this),
75
+ productData,
76
+ 0 // Prioridad alta
77
+ );
78
+ }
79
+
80
+ // Ejemplo de tarea para envío de correos
81
+ addEmailSendingTask(emailData) {
82
+ return this.expressQueue.addTask(
83
+ 'envio-correos',
84
+ this.sendEmail.bind(this),
85
+ emailData,
86
+ 0 // Prioridad alta
87
+ );
88
+ }
89
+
90
+ // Función de ejemplo para procesamiento de usuarios
91
+ async processUser(data, taskObj) {
92
+ console.log(`[PROCESAMIENTO-USUARIO] Procesando usuario:`, data.userId || data.id);
93
+
94
+ // Simular procesamiento
95
+ await new Promise(resolve => setTimeout(resolve, 2000));
96
+
97
+ console.log(`[PROCESAMIENTO-USUARIO] Usuario procesado exitosamente:`, data.userId || data.id);
98
+ return `Usuario ${data.userId || data.id} procesado exitosamente`;
99
+ }
100
+
101
+ // Función de ejemplo para procesamiento de productos
102
+ async processProduct(data, taskObj) {
103
+ console.log(`[PROCESAMIENTO-PRODUCTO] Procesando producto:`, data.productId || data.id);
104
+
105
+ // Simular procesamiento
106
+ await new Promise(resolve => setTimeout(resolve, 1500));
107
+
108
+ console.log(`[PROCESAMIENTO-PRODUCTO] Producto procesado exitosamente:`, data.productId || data.id);
109
+ return `Producto ${data.productId || data.id} procesado exitosamente`;
110
+ }
111
+
112
+ // Función de ejemplo para envío de correos
113
+ async sendEmail(data, taskObj) {
114
+ console.log(`[ENVIO-CORREO] Enviando correo a:`, data.email || data.to);
115
+
116
+ // Simular envío de correo (con 10% de probabilidad de fallo)
117
+ await new Promise(resolve => setTimeout(resolve, 1000));
118
+
119
+ if (Math.random() < 0.1) {
120
+ throw new Error(`Fallo al enviar correo a: ${data.email || data.to}`);
121
+ }
122
+
123
+ console.log(`[ENVIO-CORREO] Correo enviado exitosamente a:`, data.email || data.to);
124
+ return `Correo enviado a ${data.email || data.to} exitosamente`;
125
+ }
126
+ }
127
+
128
+ module.exports = QueueSystem;
@@ -0,0 +1,44 @@
1
+ [
2
+ {
3
+ "method": "GET",
4
+ "path": "/queue-status",
5
+ "controller": "./controllers/mainController",
6
+ "handler": "getQueueStatus",
7
+ "contentType": "application/json"
8
+ },
9
+ {
10
+ "method": "GET",
11
+ "path": "/start-queues",
12
+ "controller": "./controllers/mainController",
13
+ "handler": "startQueues",
14
+ "contentType": "application/json"
15
+ },
16
+ {
17
+ "method": "GET",
18
+ "path": "/stop-queues",
19
+ "controller": "./controllers/mainController",
20
+ "handler": "stopQueues",
21
+ "contentType": "application/json"
22
+ },
23
+ {
24
+ "method": "POST",
25
+ "path": "/process-user",
26
+ "controller": "./controllers/userController",
27
+ "handler": "processUserInQueue",
28
+ "contentType": "application/json"
29
+ },
30
+ {
31
+ "method": "POST",
32
+ "path": "/process-product",
33
+ "controller": "./controllers/productController",
34
+ "handler": "processProductInQueue",
35
+ "contentType": "application/json"
36
+ },
37
+ {
38
+ "method": "POST",
39
+ "path": "/send-email",
40
+ "controller": "./controllers/mainController",
41
+ "handler": "sendEmailInQueue",
42
+ "contentType": "application/json"
43
+ }
44
+ ]