yinzerflow 0.1.18 → 0.2.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 +0 -296
- package/YinzerFlow.d.ts +565 -0
- package/YinzerFlow.js +24 -0
- package/YinzerFlow.js.map +42 -0
- package/docs/advanced-configuration-options.md +175 -0
- package/docs/body-parsing.md +294 -0
- package/docs/cors.md +187 -0
- package/docs/ip-security.md +232 -0
- package/docs/request.md +145 -0
- package/docs/response.md +251 -0
- package/docs/start-here.MD +116 -0
- package/example/index.ts +109 -53
- package/package.json +15 -17
- package/constants/index.d.ts +0 -86
- package/constants/index.js +0 -3
- package/constants/index.js.map +0 -13
- package/docs/README.md +0 -327
- package/docs/content-types.md +0 -390
- package/docs/error-handling.md +0 -266
- package/docs/file-parsers.md +0 -276
- package/docs/hooks.md +0 -289
- package/docs/routing.md +0 -204
- package/example/bun.lock +0 -866
- package/example/hooks/authentication.middleware.ts +0 -77
- package/example/package.json +0 -61
- package/example/routes/authentication.routes.ts +0 -243
- package/example/routes/content-types.ts +0 -116
- package/example/tsconfig.json +0 -32
- package/index.d.ts +0 -395
- package/index.js +0 -23
- package/index.js.map +0 -33
package/docs/hooks.md
DELETED
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
# Request Lifecycle Hooks
|
|
2
|
-
|
|
3
|
-
YinzerFlow provides a powerful hooks system (traditionally called middleware in other frameworks) that allows you to intercept and modify requests and responses at various points in the request lifecycle. This document explains the core components, features, and best practices for using the hooks system.
|
|
4
|
-
|
|
5
|
-
## Core Concepts
|
|
6
|
-
|
|
7
|
-
In YinzerFlow, hooks are functions that can be executed at different phases of the request lifecycle:
|
|
8
|
-
|
|
9
|
-
1. **Before All**: Executed before any route-specific hooks
|
|
10
|
-
2. **Before Group**: Executed for routes in a specific group
|
|
11
|
-
3. **Before Handler**: Executed before a specific route handler
|
|
12
|
-
4. **After Handler**: Executed after a specific route handler
|
|
13
|
-
|
|
14
|
-
Each hook can:
|
|
15
|
-
- Modify the request or response
|
|
16
|
-
- End the request early by returning a response
|
|
17
|
-
- Pass control to the next hook by returning nothing
|
|
18
|
-
|
|
19
|
-
## Core Components
|
|
20
|
-
|
|
21
|
-
The hooks system consists of one main component:
|
|
22
|
-
|
|
23
|
-
### HooksManager (MiddlewareManager)
|
|
24
|
-
|
|
25
|
-
The `MiddlewareManager` class (which we recommend thinking of as a "HooksManager") is responsible for registering and executing hooks at the appropriate points in the request lifecycle.
|
|
26
|
-
|
|
27
|
-
```typescript
|
|
28
|
-
import { MiddlewareManager } from 'yinzerflow';
|
|
29
|
-
|
|
30
|
-
const hooksManager = new MiddlewareManager();
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
#### Key Features
|
|
34
|
-
|
|
35
|
-
- **Path matching**: Hooks can be applied to specific paths or path patterns
|
|
36
|
-
- **Path exclusion**: Hooks can be excluded from specific paths
|
|
37
|
-
- **Event-based architecture**: Emits events when hooks are added or executed
|
|
38
|
-
- **Error handling**: Comprehensive error handling with proper logging and propagation
|
|
39
|
-
|
|
40
|
-
## Registering Hooks
|
|
41
|
-
|
|
42
|
-
### Global Hooks
|
|
43
|
-
|
|
44
|
-
Global hooks are executed for all requests:
|
|
45
|
-
|
|
46
|
-
```typescript
|
|
47
|
-
app.beforeAll((ctx) => {
|
|
48
|
-
console.log(`Request received: ${ctx.request.method} ${ctx.request.path}`);
|
|
49
|
-
});
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
### Path-Specific Hooks
|
|
53
|
-
|
|
54
|
-
Hooks can be applied to specific paths:
|
|
55
|
-
|
|
56
|
-
```typescript
|
|
57
|
-
app.beforeAll(
|
|
58
|
-
(ctx) => {
|
|
59
|
-
// Verify API key
|
|
60
|
-
const apiKey = ctx.request.headers['x-api-key'];
|
|
61
|
-
if (!apiKey || !isValidApiKey(apiKey)) {
|
|
62
|
-
ctx.response.setStatus(401);
|
|
63
|
-
return { error: 'Invalid API key' };
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
{ paths: ['/api/users', '/api/products'] }
|
|
67
|
-
);
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
### Path Pattern Hooks
|
|
71
|
-
|
|
72
|
-
Hooks can be applied to path patterns using wildcards:
|
|
73
|
-
|
|
74
|
-
```typescript
|
|
75
|
-
app.beforeAll(
|
|
76
|
-
(ctx) => {
|
|
77
|
-
// Verify API key for all API routes
|
|
78
|
-
const apiKey = ctx.request.headers['x-api-key'];
|
|
79
|
-
if (!apiKey || !isValidApiKey(apiKey)) {
|
|
80
|
-
ctx.response.setStatus(401);
|
|
81
|
-
return { error: 'Invalid API key' };
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
{ paths: ['/api/*'] }
|
|
85
|
-
);
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Excluded Paths
|
|
89
|
-
|
|
90
|
-
Hooks can be excluded from specific paths:
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
app.beforeAll(
|
|
94
|
-
(ctx) => {
|
|
95
|
-
// Log all requests except health checks
|
|
96
|
-
console.log(`Request received: ${ctx.request.method} ${ctx.request.path}`);
|
|
97
|
-
},
|
|
98
|
-
{ paths: 'allButExcluded', excluded: ['/health'] }
|
|
99
|
-
);
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
## Route-Specific Hooks
|
|
103
|
-
|
|
104
|
-
In addition to global hooks, you can also specify hooks for specific routes:
|
|
105
|
-
|
|
106
|
-
### Before Handler
|
|
107
|
-
|
|
108
|
-
```typescript
|
|
109
|
-
app.get(
|
|
110
|
-
'/users/:id',
|
|
111
|
-
handleGetUser,
|
|
112
|
-
{
|
|
113
|
-
beforeHandler: (ctx) => {
|
|
114
|
-
// Validate user ID
|
|
115
|
-
const userId = ctx.request.params.id;
|
|
116
|
-
if (!isValidUserId(userId)) {
|
|
117
|
-
ctx.response.setStatus(400);
|
|
118
|
-
return { error: 'Invalid user ID' };
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
);
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
### After Handler
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
app.get(
|
|
129
|
-
'/users/:id',
|
|
130
|
-
handleGetUser,
|
|
131
|
-
{
|
|
132
|
-
afterHandler: (ctx) => {
|
|
133
|
-
// Log successful user retrieval
|
|
134
|
-
console.log(`User retrieved: ${ctx.request.params.id}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
);
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## Hook Execution Order
|
|
141
|
-
|
|
142
|
-
Hooks are executed in the following order:
|
|
143
|
-
|
|
144
|
-
1. Global "Before All" hooks (registered with `app.beforeAll()`)
|
|
145
|
-
2. Group "Before Group" hooks (specified when registering route groups)
|
|
146
|
-
3. Route-specific "Before Handler" hooks (specified when registering routes)
|
|
147
|
-
4. Route handler
|
|
148
|
-
5. Route-specific "After Handler" hooks (specified when registering routes)
|
|
149
|
-
|
|
150
|
-
If any hook returns a response, the request is short-circuited and that response is sent to the client.
|
|
151
|
-
|
|
152
|
-
## Response Handling and Error Management
|
|
153
|
-
|
|
154
|
-
YinzerFlow provides flexible ways to handle responses and errors in your hooks and route handlers.
|
|
155
|
-
|
|
156
|
-
### Setting Status Codes
|
|
157
|
-
|
|
158
|
-
You can set status codes directly using the response object in the context:
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
app.beforeAll((ctx) => {
|
|
162
|
-
// Check if user is authenticated
|
|
163
|
-
if (!isAuthenticated(ctx)) {
|
|
164
|
-
ctx.response.setStatus(401); // Sets status to 401 Unauthorized
|
|
165
|
-
return { message: 'Authentication required' };
|
|
166
|
-
}
|
|
167
|
-
});
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
### Returning Responses
|
|
171
|
-
|
|
172
|
-
Hooks and route handlers can return responses in several ways:
|
|
173
|
-
|
|
174
|
-
1. **Return an object**: The object will be automatically converted to JSON
|
|
175
|
-
```typescript
|
|
176
|
-
return { success: true, data: { id: 1, name: 'John' } };
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
2. **Return a primitive**: The value will be converted to a string
|
|
180
|
-
```typescript
|
|
181
|
-
return 'Hello World';
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Error Handling
|
|
185
|
-
|
|
186
|
-
For explicit error handling in hooks, use try/catch blocks:
|
|
187
|
-
|
|
188
|
-
```typescript
|
|
189
|
-
app.beforeAll(async (ctx) => {
|
|
190
|
-
try {
|
|
191
|
-
const result = await someAsyncOperation();
|
|
192
|
-
ctx.state.result = result;
|
|
193
|
-
} catch (error) {
|
|
194
|
-
console.error('Operation failed:', error);
|
|
195
|
-
ctx.response.setStatus(500);
|
|
196
|
-
return { error: 'Operation failed', message: error.message };
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
YinzerFlow has a built-in error handling system that catches unhandled errors. For more details on error handling, refer to the [Error Handling](./error-handling.md) documentation.
|
|
202
|
-
|
|
203
|
-
## Advanced Features
|
|
204
|
-
|
|
205
|
-
### Hook Events
|
|
206
|
-
|
|
207
|
-
The hooks system emits events when hooks are added or executed. You can listen for these events to perform additional actions:
|
|
208
|
-
|
|
209
|
-
```typescript
|
|
210
|
-
import { HookManagerEvent } from 'yinzerflow/constants/hooks';
|
|
211
|
-
|
|
212
|
-
app.hooks.on(HookManagerEvent.HOOK_EXECUTED, (info) => {
|
|
213
|
-
console.log(`Hook executed: ${info.phase} for ${info.path}`);
|
|
214
|
-
});
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
### Hook Removal
|
|
218
|
-
|
|
219
|
-
You can remove all hooks using the `clear` method:
|
|
220
|
-
|
|
221
|
-
```typescript
|
|
222
|
-
app.hooks.clear();
|
|
223
|
-
```
|
|
224
|
-
|
|
225
|
-
## Best Practices
|
|
226
|
-
|
|
227
|
-
### Keep Hooks Focused
|
|
228
|
-
|
|
229
|
-
Each hook should have a single responsibility. For example, separate authentication, logging, and validation into different hooks.
|
|
230
|
-
|
|
231
|
-
```typescript
|
|
232
|
-
// Good
|
|
233
|
-
app.beforeAll(logRequest);
|
|
234
|
-
app.beforeAll(authenticate);
|
|
235
|
-
app.beforeAll(validateInput);
|
|
236
|
-
|
|
237
|
-
// Avoid
|
|
238
|
-
app.beforeAll((ctx) => {
|
|
239
|
-
// Log request
|
|
240
|
-
// Authenticate user
|
|
241
|
-
// Validate input
|
|
242
|
-
});
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### Use Path Patterns Wisely
|
|
246
|
-
|
|
247
|
-
Use path patterns to apply hooks to groups of routes:
|
|
248
|
-
|
|
249
|
-
```typescript
|
|
250
|
-
// Apply authentication to all admin routes
|
|
251
|
-
app.beforeAll(authenticate, { paths: ['/admin/*'] });
|
|
252
|
-
|
|
253
|
-
// Apply rate limiting to all API routes
|
|
254
|
-
app.beforeAll(rateLimiter, { paths: ['/api/*'] });
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Error Handling
|
|
258
|
-
|
|
259
|
-
Implement proper error handling in your hooks:
|
|
260
|
-
|
|
261
|
-
```typescript
|
|
262
|
-
app.beforeAll(async (ctx) => {
|
|
263
|
-
try {
|
|
264
|
-
// Perform some async operation
|
|
265
|
-
await someAsyncOperation();
|
|
266
|
-
} catch (error) {
|
|
267
|
-
console.error('Hook error:', error);
|
|
268
|
-
ctx.response.setStatus(500);
|
|
269
|
-
return { error: 'An error occurred' };
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
### Performance Considerations
|
|
275
|
-
|
|
276
|
-
- **Keep hooks lightweight**: Hooks are executed on every matching request, so keep them efficient
|
|
277
|
-
- **Use path matching**: Apply hooks only to the paths that need them
|
|
278
|
-
- **Cache expensive operations**: If a hook performs expensive operations, consider caching the results
|
|
279
|
-
|
|
280
|
-
## Common Use Cases
|
|
281
|
-
|
|
282
|
-
- **Authentication**
|
|
283
|
-
- **Logging**
|
|
284
|
-
- **Rate Limiting**
|
|
285
|
-
|
|
286
|
-
## Conclusion
|
|
287
|
-
# End of Selection
|
|
288
|
-
|
|
289
|
-
The hooks system in YinzerFlow provides a flexible and powerful way to modify requests and responses at various points in the request lifecycle. By using hooks effectively, you can implement cross-cutting concerns like authentication, logging, and rate limiting in a clean and maintainable way.
|
package/docs/routing.md
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
# Routing System
|
|
2
|
-
|
|
3
|
-
The YinzerFlow routing system provides a flexible and efficient way to define and manage routes in your application. This document explains the core components, features, and best practices for using the routing system.
|
|
4
|
-
|
|
5
|
-
## Core Components
|
|
6
|
-
|
|
7
|
-
The routing system consists of two main components:
|
|
8
|
-
|
|
9
|
-
1. **RouteRegistry**: Responsible for storing and managing routes
|
|
10
|
-
2. **RouteFinder**: Responsible for finding and matching routes based on requests
|
|
11
|
-
|
|
12
|
-
### RouteRegistry
|
|
13
|
-
|
|
14
|
-
The `RouteRegistry` class manages the registration and storage of routes. It provides methods for adding, removing, and retrieving routes.
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
import { RouteRegistry } from 'yinzerflow';
|
|
18
|
-
|
|
19
|
-
const registry = new RouteRegistry();
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
#### Key Features
|
|
23
|
-
|
|
24
|
-
- **Event-based architecture**: Emits events when routes are added, removed, or changed
|
|
25
|
-
- **Path validation**: Validates route paths to ensure they follow proper formatting rules
|
|
26
|
-
- **Route grouping**: Supports grouping routes with common prefixes
|
|
27
|
-
- **Route removal**: Allows removing individual routes or clearing all routes
|
|
28
|
-
|
|
29
|
-
### RouteFinder
|
|
30
|
-
|
|
31
|
-
The `RouteFinder` class handles route lookup and matching. It uses efficient algorithms to find the appropriate route for a given request.
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
import { RouteFinder } from 'yinzerflow';
|
|
35
|
-
|
|
36
|
-
const finder = new RouteFinder(registry);
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
#### Key Features
|
|
40
|
-
|
|
41
|
-
- **Pattern route caching**: Caches pattern routes for faster lookup
|
|
42
|
-
- **Path normalization**: Handles trailing slashes and path normalization
|
|
43
|
-
- **Parameter extraction**: Extracts parameters from request paths
|
|
44
|
-
|
|
45
|
-
## Route Definition
|
|
46
|
-
|
|
47
|
-
Routes in YinzerFlow are defined with a path, HTTP method, and handler function. You can also specify optional middleware functions to be executed before or after the main handler.
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
app.get('/users', handleGetUsers);
|
|
51
|
-
app.post('/users', handleCreateUser);
|
|
52
|
-
app.put('/users/:id', handleUpdateUser);
|
|
53
|
-
app.delete('/users/:id', handleDeleteUser);
|
|
54
|
-
app.patch('/users/:id', handlePartialUpdateUser);
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Route Parameters
|
|
58
|
-
|
|
59
|
-
You can define route parameters by prefixing a path segment with a colon (`:`). These parameters will be extracted and made available in the request context.
|
|
60
|
-
|
|
61
|
-
```typescript
|
|
62
|
-
app.get('/users/:id', (ctx) => {
|
|
63
|
-
const userId = ctx.request.params.id;
|
|
64
|
-
// ...
|
|
65
|
-
});
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Route Groups
|
|
69
|
-
|
|
70
|
-
You can group routes with a common prefix using the `group` method:
|
|
71
|
-
|
|
72
|
-
```typescript
|
|
73
|
-
const apiRoutes = [
|
|
74
|
-
app.get('/users', handleGetUsers),
|
|
75
|
-
app.post('/users', handleCreateUser),
|
|
76
|
-
];
|
|
77
|
-
|
|
78
|
-
app.group('/api', apiRoutes);
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
This will register the routes as `/api/users` for GET and POST methods.
|
|
82
|
-
|
|
83
|
-
## Advanced Features
|
|
84
|
-
|
|
85
|
-
### Route Events
|
|
86
|
-
|
|
87
|
-
The routing system emits events when routes are added, removed, or changed. You can listen for these events to perform additional actions:
|
|
88
|
-
|
|
89
|
-
```typescript
|
|
90
|
-
import { RouteRegistryEvent } from 'yinzerflow/constants/route';
|
|
91
|
-
|
|
92
|
-
app.routeRegistry.on(RouteRegistryEvent.ROUTE_ADDED, (route) => {
|
|
93
|
-
console.log(`New route added: ${route.method} ${route.path}`);
|
|
94
|
-
});
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Route Validation
|
|
98
|
-
|
|
99
|
-
The routing system validates route paths to ensure they follow proper formatting rules:
|
|
100
|
-
|
|
101
|
-
- Paths must start with a slash
|
|
102
|
-
- Paths cannot have consecutive slashes
|
|
103
|
-
- Path parameters must have names
|
|
104
|
-
|
|
105
|
-
If a path doesn't meet these requirements, an error will be thrown:
|
|
106
|
-
|
|
107
|
-
```typescript
|
|
108
|
-
try {
|
|
109
|
-
app.get('invalid-path', handler); // Will throw an error
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.error(error.message); // "Route path must start with a slash: invalid-path"
|
|
112
|
-
}
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
### Route Removal
|
|
116
|
-
|
|
117
|
-
You can remove routes using the `removeRoute` method:
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
app.routeRegistry.removeRoute('GET', '/users/:id');
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Or clear all routes:
|
|
124
|
-
|
|
125
|
-
```typescript
|
|
126
|
-
app.routeRegistry.clearRoutes();
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
## Best Practices
|
|
130
|
-
|
|
131
|
-
### Organizing Routes
|
|
132
|
-
|
|
133
|
-
For larger applications, it's recommended to organize routes by feature or resource:
|
|
134
|
-
|
|
135
|
-
```typescript
|
|
136
|
-
// users.routes.ts
|
|
137
|
-
export function registerUserRoutes(app) {
|
|
138
|
-
app.get('/users', handleGetUsers);
|
|
139
|
-
app.post('/users', handleCreateUser);
|
|
140
|
-
// ...
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// main.ts
|
|
144
|
-
registerUserRoutes(app);
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
### Route Naming Conventions
|
|
148
|
-
|
|
149
|
-
Follow these conventions for route paths:
|
|
150
|
-
|
|
151
|
-
- Use lowercase for paths
|
|
152
|
-
- Use hyphens for multi-word resources (e.g., `/user-profiles`)
|
|
153
|
-
- Use plural nouns for resource collections (e.g., `/users` instead of `/user`)
|
|
154
|
-
- Use singular nouns with parameters for specific resources (e.g., `/users/:id`)
|
|
155
|
-
|
|
156
|
-
### Error Handling
|
|
157
|
-
|
|
158
|
-
Implement proper error handling in your route handlers:
|
|
159
|
-
|
|
160
|
-
```typescript
|
|
161
|
-
app.get('/users/:id', async (ctx) => {
|
|
162
|
-
try {
|
|
163
|
-
const user = await getUserById(ctx.request.params.id);
|
|
164
|
-
if (!user) {
|
|
165
|
-
ctx.response.setStatus(404);
|
|
166
|
-
return { error: 'User not found' };
|
|
167
|
-
}
|
|
168
|
-
return user;
|
|
169
|
-
} catch (error) {
|
|
170
|
-
console.error('Failed to retrieve user:', error);
|
|
171
|
-
ctx.response.setStatus(500);
|
|
172
|
-
return { error: 'Failed to retrieve user' };
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
For more details on error handling, refer to the [Error Handling](./error-handling.md) documentation.
|
|
178
|
-
|
|
179
|
-
## Performance Considerations
|
|
180
|
-
|
|
181
|
-
The routing system is designed to be efficient, but here are some tips to maximize performance:
|
|
182
|
-
|
|
183
|
-
- **Avoid excessive route parameters**: Each parameter adds overhead to route matching
|
|
184
|
-
- **Use route groups**: Grouping routes with common prefixes improves organization and can slightly improve performance
|
|
185
|
-
- **Order routes by specificity**: Place more specific routes before more general ones
|
|
186
|
-
|
|
187
|
-
## Debugging Routes
|
|
188
|
-
|
|
189
|
-
You can get information about registered routes using these methods:
|
|
190
|
-
|
|
191
|
-
```typescript
|
|
192
|
-
// Get all routes
|
|
193
|
-
const routes = app.routeRegistry.getRoutes();
|
|
194
|
-
|
|
195
|
-
// Check if a route exists
|
|
196
|
-
const hasRoute = app.routeRegistry.hasRoute('GET', '/users/:id');
|
|
197
|
-
|
|
198
|
-
// Get the number of registered routes
|
|
199
|
-
const routeCount = app.routeRegistry.routeCount;
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
## Conclusion
|
|
203
|
-
|
|
204
|
-
The YinzerFlow routing system provides a flexible and efficient way to define and manage routes in your application. By understanding its core components and features, you can build well-organized and performant web applications.
|