jerkjs 2.2.0 → 2.3.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/CHANGELOG.md +26 -0
- package/LICENSE +201 -0
- package/README.md +4 -1
- package/README_EN.md +230 -0
- package/README_PT.md +230 -0
- package/docs/ARQUITECTURA_ROUTES.md +186 -0
- package/docs/EXTENSION_MANUAL.md +955 -0
- package/docs/FIREWALL_MANUAL.md +416 -0
- package/docs/HOOK-2.0.md +512 -0
- package/docs/HOOKS_REFERENCE_IMPROVED.md +596 -0
- package/docs/JERK_FRAMEWORK_DIAGRAM.txt +492 -0
- package/docs/JERK_FRAMEWORK_DIAGRAM_MERMAID.mmd +124 -0
- package/docs/JERK_FRAMEWORK_DOCUMENTATION.md +553 -0
- package/docs/JERK_MODELOS_HOWTO.md +566 -0
- package/docs/MANUAL_API_SDK.md +536 -0
- package/docs/MARIADB_TOKENS_IMPLEMENTATION.md +110 -0
- package/docs/MIDDLEWARE_MANUAL.md +518 -0
- package/docs/OAUTH2_GOOGLE_MANUAL.md +405 -0
- package/docs/ROUTING_WITHOUT_JSON_GUIDE.md +454 -0
- package/docs/frontend-and-sessions.md +353 -0
- package/docs/guia_inicio_rapido_jerkjs.md +113 -0
- package/examples/examples.arj +0 -0
- package/index.js +12 -1
- package/jerk-qbuilder/CHANGELOG.md +71 -0
- package/jerk-qbuilder/HOWTO.md +325 -0
- package/jerk-qbuilder/README.md +52 -0
- package/lib/mvc/controllerBase.js +31 -14
- package/lib/query/MariaDBAdapter.js +78 -0
- package/lib/query/consoleAdapter.js +184 -0
- package/lib/query/queryBuilder.js +953 -0
- package/lib/query/queryBuilderHooks.js +455 -0
- package/lib/query/queryBuilderMiddleware.js +332 -0
- package/package.json +2 -2
- package/utils/find_file_path.sh +36 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
# Guía: Cómo añadir rutas, controladores y vistas sin utilizar routes.json
|
|
2
|
+
|
|
3
|
+
## Introducción
|
|
4
|
+
|
|
5
|
+
El framework JERK permite definir rutas, controladores y vistas de dos maneras:
|
|
6
|
+
|
|
7
|
+
1. Usando el archivo `routes.json` (método tradicional)
|
|
8
|
+
2. Usando el método `addRoute()` directamente en el código (método programático)
|
|
9
|
+
|
|
10
|
+
Esta guía explica cómo implementar la segunda opción, que permite una mayor flexibilidad y control directo sobre la definición de rutas sin depender de archivos JSON externos.
|
|
11
|
+
|
|
12
|
+
## Ventajas del enfoque sin routes.json
|
|
13
|
+
|
|
14
|
+
- **Mayor control**: Acceso directo al código de definición de rutas
|
|
15
|
+
- **Flexibilidad**: Definición dinámica de rutas basadas en condiciones en tiempo de ejecución
|
|
16
|
+
- **Integración directa**: No dependencia de archivos externos
|
|
17
|
+
- **Compatibilidad**: Todas las funcionalidades disponibles en `routes.json` también están disponibles con `addRoute()`
|
|
18
|
+
|
|
19
|
+
## Configuración del servidor
|
|
20
|
+
|
|
21
|
+
Para usar el enfoque sin `routes.json`, debes configurar tu servidor para definir rutas directamente:
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
const { APIServer, Logger, Authenticator, Cors, RateLimiter, Compressor, Firewall, SessionManager, ViewEngine, hooks } = require('jerkjs');
|
|
25
|
+
|
|
26
|
+
class MiServidor {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.server = new APIServer({
|
|
29
|
+
port: 3000,
|
|
30
|
+
host: 'localhost'
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Inicializar componentes
|
|
34
|
+
this.logger = new Logger();
|
|
35
|
+
this.authenticator = new Authenticator({ logger: this.logger });
|
|
36
|
+
this.cors = new Cors();
|
|
37
|
+
this.rateLimiter = new RateLimiter();
|
|
38
|
+
this.compressor = new Compressor({ hooks: hooks });
|
|
39
|
+
this.firewall = new Firewall({ logger: this.logger });
|
|
40
|
+
this.sessionManager = new SessionManager();
|
|
41
|
+
this.viewEngine = new ViewEngine({ hooks: hooks });
|
|
42
|
+
|
|
43
|
+
// Configurar el motor de vistas en el servidor
|
|
44
|
+
this.server.viewEngine = this.viewEngine;
|
|
45
|
+
this.viewEngine.viewsPath = './views'; // Ruta a tus vistas
|
|
46
|
+
|
|
47
|
+
// Configurar middlewares
|
|
48
|
+
this.configureMiddlewares();
|
|
49
|
+
|
|
50
|
+
// Definir rutas sin usar routes.json
|
|
51
|
+
this.defineRoutes();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
configureMiddlewares() {
|
|
55
|
+
this.server.use(this.firewall.middleware());
|
|
56
|
+
this.server.use(this.compressor.middleware());
|
|
57
|
+
this.server.use(this.cors.middleware());
|
|
58
|
+
this.server.use(this.rateLimiter.middleware());
|
|
59
|
+
this.server.use(this.sessionManager.middleware());
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
defineRoutes() {
|
|
63
|
+
// Ruta principal
|
|
64
|
+
this.server.addRoute('GET', '/', (req, res) => {
|
|
65
|
+
res.render('index', {
|
|
66
|
+
title: 'Mi Aplicación',
|
|
67
|
+
message: 'Bienvenido al servidor sin routes.json'
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// Ruta con autenticación JWT - implementación manual
|
|
72
|
+
this.server.addRoute('GET', '/dashboard', (req, res) => {
|
|
73
|
+
// Verificar token JWT manualmente
|
|
74
|
+
const authHeader = req.headers.authorization;
|
|
75
|
+
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
|
76
|
+
|
|
77
|
+
if (!token) {
|
|
78
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
79
|
+
res.end(JSON.stringify({ error: 'Token no proporcionado' }));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Verificar que JWT_SECRET esté definido en las variables de entorno
|
|
84
|
+
const jwtSecret = process.env.JWT_SECRET;
|
|
85
|
+
if (!jwtSecret) {
|
|
86
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
87
|
+
res.end(JSON.stringify({ error: 'Configuración de seguridad incompleta: JWT_SECRET no definido' }));
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const jwt = require('jsonwebtoken');
|
|
93
|
+
const decoded = jwt.verify(token, jwtSecret);
|
|
94
|
+
|
|
95
|
+
// Agregar información del usuario a la solicitud
|
|
96
|
+
req.user = decoded;
|
|
97
|
+
|
|
98
|
+
// Continuar con la lógica protegida
|
|
99
|
+
res.render('dashboard', {
|
|
100
|
+
title: 'Panel de Control',
|
|
101
|
+
user: req.user
|
|
102
|
+
});
|
|
103
|
+
} catch (error) {
|
|
104
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
105
|
+
res.end(JSON.stringify({ error: 'Token inválido o expirado' }));
|
|
106
|
+
}
|
|
107
|
+
}, {
|
|
108
|
+
contentType: 'text/html'
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
// Ruta de API con content-type JSON
|
|
112
|
+
this.server.addRoute('GET', '/api/data', (req, res) => {
|
|
113
|
+
res.end(JSON.stringify({
|
|
114
|
+
message: 'Datos de la API',
|
|
115
|
+
timestamp: new Date().toISOString()
|
|
116
|
+
}));
|
|
117
|
+
}, {
|
|
118
|
+
contentType: 'application/json'
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
start() {
|
|
123
|
+
this.server.start();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const miServidor = new MiServidor();
|
|
128
|
+
miServidor.start();
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Definición de rutas con todas las funcionalidades
|
|
132
|
+
|
|
133
|
+
El método `addRoute()` ahora soporta todas las funcionalidades que estaban disponibles en `routes.json`, aunque la implementación difiere ligeramente:
|
|
134
|
+
|
|
135
|
+
### 1. Rutas básicas
|
|
136
|
+
|
|
137
|
+
```javascript
|
|
138
|
+
// Ruta simple sin autenticación
|
|
139
|
+
server.addRoute('GET', '/', (req, res) => {
|
|
140
|
+
res.end('Hola Mundo');
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 2. Rutas con content-type
|
|
145
|
+
|
|
146
|
+
```javascript
|
|
147
|
+
// Ruta con content-type específico
|
|
148
|
+
server.addRoute('GET', '/api/users', (req, res) => {
|
|
149
|
+
res.end(JSON.stringify({ users: [] }));
|
|
150
|
+
}, {
|
|
151
|
+
contentType: 'application/json'
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### 3. Rutas con autenticación
|
|
156
|
+
|
|
157
|
+
**Importante**: A diferencia de `routes.json`, para usar autenticación con `addRoute()`, debes implementar la lógica de autenticación manualmente en el handler o registrar una estrategia de autenticación en el Authenticator:
|
|
158
|
+
|
|
159
|
+
```javascript
|
|
160
|
+
// Opción 1: Implementar autenticación JWT manualmente
|
|
161
|
+
server.addRoute('GET', '/protected', (req, res) => {
|
|
162
|
+
// Verificar token JWT manualmente
|
|
163
|
+
const authHeader = req.headers.authorization;
|
|
164
|
+
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
|
165
|
+
|
|
166
|
+
if (!token) {
|
|
167
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
168
|
+
res.end(JSON.stringify({ error: 'Token no proporcionado' }));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Verificar que JWT_SECRET esté definido en las variables de entorno
|
|
173
|
+
const jwtSecret = process.env.JWT_SECRET;
|
|
174
|
+
if (!jwtSecret) {
|
|
175
|
+
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
176
|
+
res.end(JSON.stringify({ error: 'Configuración de seguridad incompleta: JWT_SECRET no definido' }));
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const jwt = require('jsonwebtoken');
|
|
182
|
+
const decoded = jwt.verify(token, jwtSecret);
|
|
183
|
+
|
|
184
|
+
// Agregar información del usuario a la solicitud
|
|
185
|
+
req.user = decoded;
|
|
186
|
+
|
|
187
|
+
// Continuar con la lógica protegida
|
|
188
|
+
res.render('protected', { user: req.user });
|
|
189
|
+
} catch (error) {
|
|
190
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
191
|
+
res.end(JSON.stringify({ error: 'Token inválido o expirado' }));
|
|
192
|
+
}
|
|
193
|
+
}, {
|
|
194
|
+
contentType: 'text/html'
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
// Opción 2: Registrar estrategia de autenticación y usar middleware
|
|
198
|
+
// Registrar la estrategia JWT en el authenticator
|
|
199
|
+
authenticator.use('jwt-custom', async (req, options = {}) => {
|
|
200
|
+
const authHeader = req.headers.authorization;
|
|
201
|
+
const token = authHeader && authHeader.split(' ')[1];
|
|
202
|
+
|
|
203
|
+
if (!token) return false;
|
|
204
|
+
|
|
205
|
+
// Verificar que JWT_SECRET esté definido en las variables de entorno
|
|
206
|
+
const jwtSecret = process.env.JWT_SECRET;
|
|
207
|
+
if (!jwtSecret) {
|
|
208
|
+
console.error('ERROR: JWT_SECRET no está definido en las variables de entorno');
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
const jwt = require('jsonwebtoken');
|
|
214
|
+
const decoded = jwt.verify(token, jwtSecret);
|
|
215
|
+
req.user = decoded;
|
|
216
|
+
return true;
|
|
217
|
+
} catch (error) {
|
|
218
|
+
return false;
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
// Luego usar el middleware de autenticación
|
|
223
|
+
server.addRoute('GET', '/protected',
|
|
224
|
+
authenticator.authenticate('jwt-custom', {})((req, res) => {
|
|
225
|
+
// Esta ruta está protegida
|
|
226
|
+
res.render('protected', { user: req.user });
|
|
227
|
+
}), {
|
|
228
|
+
contentType: 'text/html'
|
|
229
|
+
}
|
|
230
|
+
);
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### 4. Rutas con vistas y variables
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
// Ruta que renderiza una vista con variables
|
|
237
|
+
server.addRoute('GET', '/profile', (req, res) => {
|
|
238
|
+
res.render('profile', {
|
|
239
|
+
user: { name: 'Juan', email: 'juan@example.com' },
|
|
240
|
+
title: 'Perfil de Usuario'
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Creación de controladores sin routes.json
|
|
246
|
+
|
|
247
|
+
Puedes crear controladores que extiendan `ControllerBase` y usarlos con el enfoque programático:
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
// controllers/HomeController.js
|
|
251
|
+
const ControllerBase = require('../lib/mvc/controllerBase');
|
|
252
|
+
|
|
253
|
+
class HomeController extends ControllerBase {
|
|
254
|
+
constructor(options = {}) {
|
|
255
|
+
super(options);
|
|
256
|
+
this.viewsPath = './views'; // Ruta a las vistas
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
index(req, res) {
|
|
260
|
+
this.set('title', 'Página de Inicio');
|
|
261
|
+
this.set('message', 'Bienvenido a mi aplicación');
|
|
262
|
+
this.set('users', [
|
|
263
|
+
{ id: 1, name: 'Juan' },
|
|
264
|
+
{ id: 2, name: 'Ana' }
|
|
265
|
+
]);
|
|
266
|
+
|
|
267
|
+
this.render(res, 'home/index');
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
showUser(req, res) {
|
|
271
|
+
const userId = req.params.id;
|
|
272
|
+
this.set('title', `Usuario ${userId}`);
|
|
273
|
+
this.set('user', { id: userId, name: `Usuario ${userId}` });
|
|
274
|
+
|
|
275
|
+
this.render(res, 'user/show');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
module.exports = new HomeController();
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Y luego usarlo en tu servidor:
|
|
283
|
+
|
|
284
|
+
```javascript
|
|
285
|
+
const HomeController = require('./controllers/HomeController');
|
|
286
|
+
|
|
287
|
+
server.addRoute('GET', '/', (req, res) => {
|
|
288
|
+
HomeController.setRequestResponse(req, res);
|
|
289
|
+
HomeController.index(req, res);
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
server.addRoute('GET', '/users/:id', (req, res) => {
|
|
293
|
+
HomeController.setRequestResponse(req, res);
|
|
294
|
+
HomeController.showUser(req, res);
|
|
295
|
+
});
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
## Creación de vistas con variables y estructuras complejas
|
|
299
|
+
|
|
300
|
+
Las vistas pueden usar todas las funcionalidades del motor de plantillas:
|
|
301
|
+
|
|
302
|
+
### Vista básica con variables
|
|
303
|
+
```html
|
|
304
|
+
<!-- views/home/index.html -->
|
|
305
|
+
<!DOCTYPE html>
|
|
306
|
+
<html>
|
|
307
|
+
<head>
|
|
308
|
+
<title>{{title}}</title>
|
|
309
|
+
</head>
|
|
310
|
+
<body>
|
|
311
|
+
<h1>{{title}}</h1>
|
|
312
|
+
<p>{{message}}</p>
|
|
313
|
+
|
|
314
|
+
{{if users}}
|
|
315
|
+
<ul>
|
|
316
|
+
{{foreach:users}}
|
|
317
|
+
<li>{{item.name}}</li>
|
|
318
|
+
{{endforeach}}
|
|
319
|
+
</ul>
|
|
320
|
+
{{else}}
|
|
321
|
+
<p>No hay usuarios disponibles.</p>
|
|
322
|
+
{{endif}}
|
|
323
|
+
</body>
|
|
324
|
+
</html>
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
### Vista con estructuras condicionales y bucles
|
|
328
|
+
```html
|
|
329
|
+
<!-- views/user/show.html -->
|
|
330
|
+
<!DOCTYPE html>
|
|
331
|
+
<html>
|
|
332
|
+
<head>
|
|
333
|
+
<title>{{title}}</title>
|
|
334
|
+
</head>
|
|
335
|
+
<body>
|
|
336
|
+
<h1>{{user.name}}</h1>
|
|
337
|
+
<p>ID: {{user.id}}</p>
|
|
338
|
+
|
|
339
|
+
{{if user.active}}
|
|
340
|
+
<span class="active">Activo</span>
|
|
341
|
+
{{else}}
|
|
342
|
+
<span class="inactive">Inactivo</span>
|
|
343
|
+
{{endif}}
|
|
344
|
+
</body>
|
|
345
|
+
</html>
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
## Errores comunes y soluciones
|
|
349
|
+
|
|
350
|
+
### 1. Variables no se reemplazan en vistas
|
|
351
|
+
|
|
352
|
+
**Problema**: Las variables `{{variable}}` no se reemplazan en las vistas.
|
|
353
|
+
|
|
354
|
+
**Solución**: Asegúrate de que:
|
|
355
|
+
- El `ViewEngine` esté correctamente configurado en el servidor
|
|
356
|
+
- La ruta de vistas esté correctamente especificada
|
|
357
|
+
- Las variables se estén pasando correctamente al método `render()`
|
|
358
|
+
|
|
359
|
+
### 2. Autenticación no funciona con addRoute()
|
|
360
|
+
|
|
361
|
+
**Problema**: La autenticación no se aplica cuando se usa `addRoute()`.
|
|
362
|
+
|
|
363
|
+
**Solución**: A diferencia de `routes.json`, `addRoute()` no acepta directamente las opciones `auth` y `authOptions`. Debes implementar la lógica de autenticación manualmente en el handler o usar el sistema de autenticación del framework como middleware:
|
|
364
|
+
|
|
365
|
+
```javascript
|
|
366
|
+
// Solución 1: Implementar autenticación manualmente en el handler
|
|
367
|
+
server.addRoute('GET', '/protected', (req, res) => {
|
|
368
|
+
const authHeader = req.headers.authorization;
|
|
369
|
+
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN
|
|
370
|
+
|
|
371
|
+
if (!token) {
|
|
372
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
373
|
+
res.end(JSON.stringify({ error: 'Token no proporcionado' }));
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
try {
|
|
378
|
+
const jwt = require('jsonwebtoken');
|
|
379
|
+
const decoded = jwt.verify(token, process.env.JWT_SECRET);
|
|
380
|
+
req.user = decoded;
|
|
381
|
+
|
|
382
|
+
// Continuar con la lógica protegida
|
|
383
|
+
res.render('protected', { user: req.user });
|
|
384
|
+
} catch (error) {
|
|
385
|
+
res.writeHead(401, { 'Content-Type': 'application/json' });
|
|
386
|
+
res.end(JSON.stringify({ error: 'Token inválido o expirado' }));
|
|
387
|
+
}
|
|
388
|
+
}, {
|
|
389
|
+
contentType: 'text/html'
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Solución 2: Usar el sistema de autenticación como middleware
|
|
393
|
+
// Registrar la estrategia de autenticación
|
|
394
|
+
authenticator.use('jwt-middleware', async (req, options = {}) => {
|
|
395
|
+
const authHeader = req.headers.authorization;
|
|
396
|
+
const token = authHeader && authHeader.split(' ')[1];
|
|
397
|
+
|
|
398
|
+
if (!token) return false;
|
|
399
|
+
|
|
400
|
+
// Verificar que JWT_SECRET esté definido en las variables de entorno
|
|
401
|
+
const jwtSecret = process.env.JWT_SECRET;
|
|
402
|
+
if (!jwtSecret) {
|
|
403
|
+
console.error('ERROR: JWT_SECRET no está definido en las variables de entorno');
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
const jwt = require('jsonwebtoken');
|
|
409
|
+
const decoded = jwt.verify(token, jwtSecret);
|
|
410
|
+
req.user = decoded;
|
|
411
|
+
return true;
|
|
412
|
+
} catch (error) {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// Aplicar el middleware de autenticación a la ruta
|
|
418
|
+
server.addRoute('GET', '/protected',
|
|
419
|
+
authenticator.authenticate('jwt-middleware', {})((req, res) => {
|
|
420
|
+
res.render('protected', { user: req.user });
|
|
421
|
+
}), {
|
|
422
|
+
contentType: 'text/html'
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
### 3. Rutas parametrizadas no funcionan
|
|
428
|
+
|
|
429
|
+
**Problema**: Las rutas como `/users/:id` no capturan los parámetros.
|
|
430
|
+
|
|
431
|
+
**Solución**: Los parámetros están disponibles en `req.params`:
|
|
432
|
+
|
|
433
|
+
```javascript
|
|
434
|
+
server.addRoute('GET', '/users/:id', (req, res) => {
|
|
435
|
+
const userId = req.params.id; // Aquí está el valor del parámetro
|
|
436
|
+
res.end(`Usuario ID: ${userId}`);
|
|
437
|
+
});
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
## Buenas prácticas
|
|
441
|
+
|
|
442
|
+
1. **Organiza tus rutas**: Agrupa rutas relacionadas en funciones separadas
|
|
443
|
+
2. **Usa controladores**: Extiende `ControllerBase` para lógica compleja
|
|
444
|
+
3. **Configura correctamente el ViewEngine**: Asegúrate de que la ruta de vistas esté correctamente configurada
|
|
445
|
+
4. **Maneja errores**: Implementa manejo de errores adecuado
|
|
446
|
+
5. **Documenta tus rutas**: Aunque no uses `routes.json`, documenta tus rutas programáticas
|
|
447
|
+
6. **Implementa autenticación manualmente**: Para usar autenticación con `addRoute()`, implementa la lógica manualmente o registra estrategias de autenticación
|
|
448
|
+
7. **Usa el sistema de hooks**: Aprovecha el sistema de hooks y filters para extensibilidad
|
|
449
|
+
|
|
450
|
+
## Conclusión
|
|
451
|
+
|
|
452
|
+
El enfoque sin `routes.json` ofrece una alternativa poderosa y flexible para definir rutas en JERK Framework. Con las mejoras implementadas, ahora puedes usar `addRoute()` con todas las funcionalidades equivalentes a las disponibles en `routes.json`, incluyendo autenticación (implementada manualmente o con middleware), content-type, vistas con variables anidadas y más.
|
|
453
|
+
|
|
454
|
+
Esta arquitectura permite una mayor flexibilidad y control sobre la definición de rutas, ideal para aplicaciones que requieren lógica dinámica en la definición de endpoints. Ambas arquitecturas (con y sin `routes.json`) ofrecen las mismas funcionalidades y pueden usarse según las necesidades del proyecto.
|