@engjts/nexus 0.1.8 → 0.1.10
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/dist/advanced/playground/playground.js.map +1 -1
- package/dist/advanced/static/generateDirectoryListing.d.ts +1 -1
- package/dist/advanced/static/generateDirectoryListing.d.ts.map +1 -1
- package/dist/advanced/static/generateDirectoryListing.js +12 -6
- package/dist/advanced/static/generateDirectoryListing.js.map +1 -1
- package/dist/advanced/static/index.d.ts +2 -0
- package/dist/advanced/static/index.d.ts.map +1 -1
- package/dist/advanced/static/index.js +4 -1
- package/dist/advanced/static/index.js.map +1 -1
- package/dist/advanced/static/serveStatic.d.ts.map +1 -1
- package/dist/advanced/static/serveStatic.js +7 -1
- package/dist/advanced/static/serveStatic.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/BENCHMARK_REPORT.md +0 -343
- package/documentation/01-getting-started.md +0 -240
- package/documentation/02-context.md +0 -335
- package/documentation/03-routing.md +0 -397
- package/documentation/04-middleware.md +0 -483
- package/documentation/05-validation.md +0 -514
- package/documentation/06-error-handling.md +0 -465
- package/documentation/07-performance.md +0 -364
- package/documentation/08-adapters.md +0 -470
- package/documentation/09-api-reference.md +0 -548
- package/documentation/10-examples.md +0 -582
- package/documentation/11-deployment.md +0 -477
- package/documentation/12-sentry.md +0 -620
- package/documentation/13-sentry-data-storage.md +0 -996
- package/documentation/14-sentry-data-reference.md +0 -457
- package/documentation/15-sentry-summary.md +0 -409
- package/documentation/16-alerts-system.md +0 -745
- package/documentation/17-alert-adapters.md +0 -696
- package/documentation/18-alerts-implementation-summary.md +0 -385
- package/documentation/19-class-based-routing.md +0 -840
- package/documentation/20-websocket-realtime.md +0 -813
- package/documentation/21-cache-system.md +0 -510
- package/documentation/22-job-queue.md +0 -772
- package/documentation/23-sentry-plugin.md +0 -551
- package/documentation/24-testing-utilities.md +0 -1287
- package/documentation/25-api-versioning.md +0 -533
- package/documentation/26-context-store.md +0 -607
- package/documentation/27-dependency-injection.md +0 -329
- package/documentation/28-lifecycle-hooks.md +0 -521
- package/documentation/29-package-structure.md +0 -196
- package/documentation/30-plugin-system.md +0 -414
- package/documentation/31-jwt-authentication.md +0 -597
- package/documentation/32-cli.md +0 -268
- package/documentation/ALERTS-COMPLETE-SUMMARY.md +0 -429
- package/documentation/ALERTS-INDEX.md +0 -330
- package/documentation/ALERTS-QUICK-REFERENCE.md +0 -286
- package/documentation/README.md +0 -178
- package/documentation/index.html +0 -34
- package/modern_framework_paper.md +0 -1870
- package/public/css/style.css +0 -87
- package/public/index.html +0 -34
- package/public/js/app.js +0 -27
- package/src/advanced/cache/InMemoryCacheStore.ts +0 -68
- package/src/advanced/cache/MultiTierCache.ts +0 -194
- package/src/advanced/cache/RedisCacheStore.ts +0 -341
- package/src/advanced/cache/index.ts +0 -5
- package/src/advanced/cache/types.ts +0 -40
- package/src/advanced/graphql/SimpleDataLoader.ts +0 -42
- package/src/advanced/graphql/index.ts +0 -22
- package/src/advanced/graphql/server.ts +0 -252
- package/src/advanced/graphql/types.ts +0 -42
- package/src/advanced/jobs/InMemoryQueueStore.ts +0 -68
- package/src/advanced/jobs/JobQueue.ts +0 -556
- package/src/advanced/jobs/RedisQueueStore.ts +0 -367
- package/src/advanced/jobs/index.ts +0 -5
- package/src/advanced/jobs/types.ts +0 -70
- package/src/advanced/observability/APMManager.ts +0 -163
- package/src/advanced/observability/AlertManager.ts +0 -109
- package/src/advanced/observability/MetricRegistry.ts +0 -151
- package/src/advanced/observability/ObservabilityCenter.ts +0 -304
- package/src/advanced/observability/StructuredLogger.ts +0 -154
- package/src/advanced/observability/TracingManager.ts +0 -117
- package/src/advanced/observability/adapters.ts +0 -304
- package/src/advanced/observability/createObservabilityMiddleware.ts +0 -63
- package/src/advanced/observability/index.ts +0 -11
- package/src/advanced/observability/types.ts +0 -174
- package/src/advanced/playground/extractPathParams.ts +0 -6
- package/src/advanced/playground/generateFieldExample.ts +0 -31
- package/src/advanced/playground/generatePlaygroundHTML.ts +0 -1956
- package/src/advanced/playground/generateSummary.ts +0 -19
- package/src/advanced/playground/getTagFromPath.ts +0 -9
- package/src/advanced/playground/index.ts +0 -8
- package/src/advanced/playground/playground.ts +0 -250
- package/src/advanced/playground/types.ts +0 -49
- package/src/advanced/playground/zodToExample.ts +0 -16
- package/src/advanced/playground/zodToParams.ts +0 -15
- package/src/advanced/postman/buildAuth.ts +0 -31
- package/src/advanced/postman/buildBody.ts +0 -15
- package/src/advanced/postman/buildQueryParams.ts +0 -27
- package/src/advanced/postman/buildRequestItem.ts +0 -36
- package/src/advanced/postman/buildResponses.ts +0 -11
- package/src/advanced/postman/buildUrl.ts +0 -33
- package/src/advanced/postman/capitalize.ts +0 -4
- package/src/advanced/postman/generateCollection.ts +0 -59
- package/src/advanced/postman/generateEnvironment.ts +0 -34
- package/src/advanced/postman/generateExampleFromZod.ts +0 -21
- package/src/advanced/postman/generateFieldExample.ts +0 -45
- package/src/advanced/postman/generateName.ts +0 -20
- package/src/advanced/postman/generateUUID.ts +0 -11
- package/src/advanced/postman/getTagFromPath.ts +0 -10
- package/src/advanced/postman/index.ts +0 -28
- package/src/advanced/postman/postman.ts +0 -156
- package/src/advanced/postman/slugify.ts +0 -7
- package/src/advanced/postman/types.ts +0 -140
- package/src/advanced/realtime/index.ts +0 -18
- package/src/advanced/realtime/websocket.ts +0 -231
- package/src/advanced/sentry/index.ts +0 -1236
- package/src/advanced/sentry/types.ts +0 -355
- package/src/advanced/static/generateDirectoryListing.ts +0 -47
- package/src/advanced/static/generateETag.ts +0 -7
- package/src/advanced/static/getMimeType.ts +0 -9
- package/src/advanced/static/index.ts +0 -32
- package/src/advanced/static/isSafePath.ts +0 -13
- package/src/advanced/static/publicDir.ts +0 -21
- package/src/advanced/static/serveStatic.ts +0 -225
- package/src/advanced/static/spa.ts +0 -24
- package/src/advanced/static/types.ts +0 -159
- package/src/advanced/swagger/SwaggerGenerator.ts +0 -66
- package/src/advanced/swagger/buildOperation.ts +0 -61
- package/src/advanced/swagger/buildParameters.ts +0 -61
- package/src/advanced/swagger/buildRequestBody.ts +0 -21
- package/src/advanced/swagger/buildResponses.ts +0 -54
- package/src/advanced/swagger/capitalize.ts +0 -5
- package/src/advanced/swagger/convertPath.ts +0 -9
- package/src/advanced/swagger/createSwagger.ts +0 -12
- package/src/advanced/swagger/generateOperationId.ts +0 -21
- package/src/advanced/swagger/generateSpec.ts +0 -105
- package/src/advanced/swagger/generateSummary.ts +0 -24
- package/src/advanced/swagger/generateSwaggerUI.ts +0 -70
- package/src/advanced/swagger/generateThemeCss.ts +0 -53
- package/src/advanced/swagger/index.ts +0 -25
- package/src/advanced/swagger/swagger.ts +0 -237
- package/src/advanced/swagger/types.ts +0 -206
- package/src/advanced/swagger/zodFieldToOpenAPI.ts +0 -94
- package/src/advanced/swagger/zodSchemaToOpenAPI.ts +0 -50
- package/src/advanced/swagger/zodToOpenAPI.ts +0 -22
- package/src/advanced/testing/factory.ts +0 -509
- package/src/advanced/testing/harness.ts +0 -612
- package/src/advanced/testing/index.ts +0 -430
- package/src/advanced/testing/load-test.ts +0 -618
- package/src/advanced/testing/mock-server.ts +0 -498
- package/src/advanced/testing/mock.ts +0 -670
- package/src/cli/bin.ts +0 -9
- package/src/cli/cli.ts +0 -158
- package/src/cli/commands/add.ts +0 -178
- package/src/cli/commands/build.ts +0 -73
- package/src/cli/commands/create.ts +0 -166
- package/src/cli/commands/dev.ts +0 -85
- package/src/cli/commands/generate.ts +0 -99
- package/src/cli/commands/help.ts +0 -95
- package/src/cli/commands/init.ts +0 -91
- package/src/cli/commands/version.ts +0 -38
- package/src/cli/index.ts +0 -6
- package/src/cli/templates/generators.ts +0 -359
- package/src/cli/templates/index.ts +0 -680
- package/src/cli/utils/exec.ts +0 -52
- package/src/cli/utils/file-system.ts +0 -78
- package/src/cli/utils/logger.ts +0 -111
- package/src/core/adapter.ts +0 -88
- package/src/core/application.ts +0 -1453
- package/src/core/context-pool.ts +0 -79
- package/src/core/context.ts +0 -856
- package/src/core/index.ts +0 -94
- package/src/core/middleware.ts +0 -272
- package/src/core/performance/buffer-pool.ts +0 -108
- package/src/core/performance/middleware-optimizer.ts +0 -162
- package/src/core/plugin/PluginManager.ts +0 -435
- package/src/core/plugin/builder.ts +0 -358
- package/src/core/plugin/index.ts +0 -50
- package/src/core/plugin/types.ts +0 -214
- package/src/core/router/file-router.ts +0 -623
- package/src/core/router/index.ts +0 -260
- package/src/core/router/radix-tree.ts +0 -242
- package/src/core/serializer.ts +0 -397
- package/src/core/store/index.ts +0 -30
- package/src/core/store/registry.ts +0 -178
- package/src/core/store/request-store.ts +0 -240
- package/src/core/store/types.ts +0 -233
- package/src/core/types.ts +0 -616
- package/src/database/adapter.ts +0 -35
- package/src/database/adapters/index.ts +0 -1
- package/src/database/adapters/mysql.ts +0 -669
- package/src/database/database.ts +0 -70
- package/src/database/dialect.ts +0 -388
- package/src/database/index.ts +0 -12
- package/src/database/migrations.ts +0 -86
- package/src/database/optimizer.ts +0 -125
- package/src/database/query-builder.ts +0 -404
- package/src/database/realtime.ts +0 -53
- package/src/database/schema.ts +0 -71
- package/src/database/transactions.ts +0 -56
- package/src/database/types.ts +0 -87
- package/src/deployment/cluster.ts +0 -471
- package/src/deployment/config.ts +0 -454
- package/src/deployment/docker.ts +0 -599
- package/src/deployment/graceful-shutdown.ts +0 -373
- package/src/deployment/index.ts +0 -56
- package/src/index.ts +0 -281
- package/src/security/adapter.ts +0 -318
- package/src/security/auth/JWTPlugin.ts +0 -234
- package/src/security/auth/JWTProvider.ts +0 -316
- package/src/security/auth/adapter.ts +0 -12
- package/src/security/auth/jwt.ts +0 -234
- package/src/security/auth/middleware.ts +0 -188
- package/src/security/csrf.ts +0 -220
- package/src/security/headers.ts +0 -108
- package/src/security/index.ts +0 -60
- package/src/security/rate-limit/adapter.ts +0 -7
- package/src/security/rate-limit/memory.ts +0 -108
- package/src/security/rate-limit/middleware.ts +0 -181
- package/src/security/sanitization.ts +0 -75
- package/src/security/types.ts +0 -240
- package/src/security/utils.ts +0 -52
- package/tsconfig.json +0 -39
|
@@ -1,397 +0,0 @@
|
|
|
1
|
-
# Routing Guide
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Nexus uses a **Radix Tree** for routing, providing O(log n) lookup performance. The routing system supports static routes, dynamic parameters, and wildcards.
|
|
6
|
-
|
|
7
|
-
## Basic Routes
|
|
8
|
-
|
|
9
|
-
### Static Routes
|
|
10
|
-
|
|
11
|
-
```typescript
|
|
12
|
-
app.get('/about', async (ctx) => {
|
|
13
|
-
return { page: 'about' };
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
app.get('/api/users', async (ctx) => {
|
|
17
|
-
return { users: [] };
|
|
18
|
-
});
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### HTTP Methods
|
|
22
|
-
|
|
23
|
-
```typescript
|
|
24
|
-
app.get('/resource', async (ctx) => {
|
|
25
|
-
return { method: 'GET' };
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
app.post('/resource', async (ctx) => {
|
|
29
|
-
return { method: 'POST', body: ctx.body };
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
app.put('/resource/:id', async (ctx) => {
|
|
33
|
-
return { method: 'PUT', id: ctx.params.id };
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
app.patch('/resource/:id', async (ctx) => {
|
|
37
|
-
return { method: 'PATCH', id: ctx.params.id };
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
app.delete('/resource/:id', async (ctx) => {
|
|
41
|
-
return { method: 'DELETE', id: ctx.params.id };
|
|
42
|
-
});
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Dynamic Routes
|
|
46
|
-
|
|
47
|
-
### Single Parameter
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
app.get('/users/:id', async (ctx) => {
|
|
51
|
-
const userId = ctx.params.id;
|
|
52
|
-
const user = await getUser(userId);
|
|
53
|
-
return { user };
|
|
54
|
-
});
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### Multiple Parameters
|
|
58
|
-
|
|
59
|
-
```typescript
|
|
60
|
-
app.get('/users/:userId/posts/:postId', async (ctx) => {
|
|
61
|
-
const { userId, postId } = ctx.params;
|
|
62
|
-
const post = await getPost(userId, postId);
|
|
63
|
-
return { post };
|
|
64
|
-
});
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
### Parameter Naming
|
|
68
|
-
|
|
69
|
-
Use descriptive parameter names:
|
|
70
|
-
|
|
71
|
-
```typescript
|
|
72
|
-
// Good
|
|
73
|
-
app.get('/articles/:articleId/comments/:commentId', ...);
|
|
74
|
-
|
|
75
|
-
// Avoid
|
|
76
|
-
app.get('/articles/:id1/comments/:id2', ...);
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Wildcard Routes
|
|
80
|
-
|
|
81
|
-
Capture the remaining path with `*`:
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
app.get('/files/*filepath', async (ctx) => {
|
|
85
|
-
const filepath = ctx.params.filepath;
|
|
86
|
-
// filepath = "docs/guide/intro.md" for /files/docs/guide/intro.md
|
|
87
|
-
return { filepath };
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
app.get('/proxy/*', async (ctx) => {
|
|
91
|
-
const path = ctx.params.wildcard; // default name
|
|
92
|
-
return { proxiedPath: path };
|
|
93
|
-
});
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## Route Priority
|
|
97
|
-
|
|
98
|
-
Routes are matched in this order:
|
|
99
|
-
|
|
100
|
-
1. **Static** - Exact matches
|
|
101
|
-
2. **Parameters** - Dynamic segments (`:param`)
|
|
102
|
-
3. **Wildcards** - Catch-all (`*`)
|
|
103
|
-
|
|
104
|
-
```typescript
|
|
105
|
-
app.get('/users/active', ...); // 1. Matched first
|
|
106
|
-
app.get('/users/:id', ...); // 2. Matched second
|
|
107
|
-
app.get('/users/*', ...); // 3. Matched last
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
Example:
|
|
111
|
-
- `/users/active` → matches static route
|
|
112
|
-
- `/users/123` → matches parameter route
|
|
113
|
-
- `/users/admin/settings` → matches wildcard route
|
|
114
|
-
|
|
115
|
-
## Declarative Route Definition
|
|
116
|
-
|
|
117
|
-
Use the `route()` method for advanced configuration:
|
|
118
|
-
|
|
119
|
-
```typescript
|
|
120
|
-
import { z } from 'zod';
|
|
121
|
-
|
|
122
|
-
app.route({
|
|
123
|
-
method: 'POST',
|
|
124
|
-
path: '/api/users',
|
|
125
|
-
|
|
126
|
-
// Schema validation
|
|
127
|
-
schema: {
|
|
128
|
-
body: z.object({
|
|
129
|
-
name: z.string().min(2),
|
|
130
|
-
email: z.string().email()
|
|
131
|
-
})
|
|
132
|
-
},
|
|
133
|
-
|
|
134
|
-
// Middleware
|
|
135
|
-
middlewares: [authenticate, rateLimit],
|
|
136
|
-
|
|
137
|
-
// Handler
|
|
138
|
-
handler: async (ctx) => {
|
|
139
|
-
const user = await createUser(ctx.body);
|
|
140
|
-
return { user };
|
|
141
|
-
},
|
|
142
|
-
|
|
143
|
-
// Metadata (for documentation)
|
|
144
|
-
meta: {
|
|
145
|
-
description: 'Create a new user',
|
|
146
|
-
tags: ['users'],
|
|
147
|
-
responses: {
|
|
148
|
-
201: 'User created',
|
|
149
|
-
400: 'Validation error'
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
## Route Groups
|
|
156
|
-
|
|
157
|
-
Organize routes by creating separate router modules:
|
|
158
|
-
|
|
159
|
-
### `routes/users.ts`
|
|
160
|
-
|
|
161
|
-
```typescript
|
|
162
|
-
import { Router } from '../nexus';
|
|
163
|
-
|
|
164
|
-
export const userRoutes = (app: Application) => {
|
|
165
|
-
app.get('/users', async (ctx) => {
|
|
166
|
-
return { users: await getUsers() };
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
app.get('/users/:id', async (ctx) => {
|
|
170
|
-
return { user: await getUser(ctx.params.id) };
|
|
171
|
-
});
|
|
172
|
-
|
|
173
|
-
app.post('/users', {
|
|
174
|
-
schema: { /* ... */ },
|
|
175
|
-
handler: async (ctx) => { /* ... */ }
|
|
176
|
-
});
|
|
177
|
-
};
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### `index.ts`
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
import { createApp } from './nexus';
|
|
184
|
-
import { userRoutes } from './routes/users';
|
|
185
|
-
import { postRoutes } from './routes/posts';
|
|
186
|
-
|
|
187
|
-
const app = createApp();
|
|
188
|
-
|
|
189
|
-
userRoutes(app);
|
|
190
|
-
postRoutes(app);
|
|
191
|
-
|
|
192
|
-
app.listen(3000);
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
## Route Prefixes
|
|
196
|
-
|
|
197
|
-
Create prefixed route groups:
|
|
198
|
-
|
|
199
|
-
```typescript
|
|
200
|
-
const createAPIRoutes = (app: Application, prefix: string) => {
|
|
201
|
-
app.get(`${prefix}/users`, ...);
|
|
202
|
-
app.get(`${prefix}/posts`, ...);
|
|
203
|
-
app.get(`${prefix}/comments`, ...);
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
createAPIRoutes(app, '/api/v1');
|
|
207
|
-
createAPIRoutes(app, '/api/v2');
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
## Query Parameters
|
|
211
|
-
|
|
212
|
-
Access query parameters via `ctx.query`:
|
|
213
|
-
|
|
214
|
-
```typescript
|
|
215
|
-
// GET /search?q=nexus&page=2&limit=20
|
|
216
|
-
app.get('/search', async (ctx) => {
|
|
217
|
-
const query = ctx.query.q;
|
|
218
|
-
const page = parseInt(ctx.query.page) || 1;
|
|
219
|
-
const limit = parseInt(ctx.query.limit) || 10;
|
|
220
|
-
|
|
221
|
-
const results = await search(query, page, limit);
|
|
222
|
-
return { results, page, limit };
|
|
223
|
-
});
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Type-Safe Query Validation
|
|
227
|
-
|
|
228
|
-
```typescript
|
|
229
|
-
import { z } from 'zod';
|
|
230
|
-
|
|
231
|
-
app.get('/search', {
|
|
232
|
-
schema: {
|
|
233
|
-
query: z.object({
|
|
234
|
-
q: z.string().min(1),
|
|
235
|
-
page: z.string().regex(/^\d+$/).transform(Number).default('1'),
|
|
236
|
-
limit: z.string().regex(/^\d+$/).transform(Number).default('10')
|
|
237
|
-
})
|
|
238
|
-
},
|
|
239
|
-
handler: async (ctx) => {
|
|
240
|
-
// ctx.query is now typed and validated
|
|
241
|
-
const { q, page, limit } = ctx.query;
|
|
242
|
-
return await search(q, page, limit);
|
|
243
|
-
}
|
|
244
|
-
});
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
## 404 Not Found
|
|
248
|
-
|
|
249
|
-
Nexus automatically returns 404 for unmatched routes:
|
|
250
|
-
|
|
251
|
-
```json
|
|
252
|
-
{
|
|
253
|
-
"error": "Not Found"
|
|
254
|
-
}
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
Custom 404 handler:
|
|
258
|
-
|
|
259
|
-
```typescript
|
|
260
|
-
// Add a wildcard route at the end
|
|
261
|
-
app.get('/*', async (ctx) => {
|
|
262
|
-
return ctx.response.status(404).json({
|
|
263
|
-
error: 'Page not found',
|
|
264
|
-
path: ctx.path
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
## Route Introspection
|
|
270
|
-
|
|
271
|
-
Get all registered routes:
|
|
272
|
-
|
|
273
|
-
```typescript
|
|
274
|
-
const routes = app.getRoutes();
|
|
275
|
-
console.log(routes);
|
|
276
|
-
// [
|
|
277
|
-
// { method: 'GET', path: '/users' },
|
|
278
|
-
// { method: 'GET', path: '/users/:id' },
|
|
279
|
-
// { method: 'POST', path: '/users' }
|
|
280
|
-
// ]
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
Useful for:
|
|
284
|
-
- Generating API documentation
|
|
285
|
-
- Debugging route conflicts
|
|
286
|
-
- Creating route lists
|
|
287
|
-
|
|
288
|
-
## Best Practices
|
|
289
|
-
|
|
290
|
-
### ✅ DO: Use RESTful conventions
|
|
291
|
-
|
|
292
|
-
```typescript
|
|
293
|
-
app.get('/users', ...); // List users
|
|
294
|
-
app.get('/users/:id', ...); // Get user
|
|
295
|
-
app.post('/users', ...); // Create user
|
|
296
|
-
app.put('/users/:id', ...); // Update user (full)
|
|
297
|
-
app.patch('/users/:id', ...); // Update user (partial)
|
|
298
|
-
app.delete('/users/:id', ...); // Delete user
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
### ✅ DO: Version your API
|
|
302
|
-
|
|
303
|
-
```typescript
|
|
304
|
-
app.get('/api/v1/users', ...);
|
|
305
|
-
app.get('/api/v2/users', ...);
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
### ✅ DO: Use specific routes before wildcards
|
|
309
|
-
|
|
310
|
-
```typescript
|
|
311
|
-
// Correct order
|
|
312
|
-
app.get('/admin/dashboard', ...);
|
|
313
|
-
app.get('/admin/*', ...);
|
|
314
|
-
|
|
315
|
-
// Wrong order - dashboard will never be reached
|
|
316
|
-
app.get('/admin/*', ...);
|
|
317
|
-
app.get('/admin/dashboard', ...);
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
### ❌ DON'T: Create ambiguous routes
|
|
321
|
-
|
|
322
|
-
```typescript
|
|
323
|
-
// Ambiguous - which route matches /users/123?
|
|
324
|
-
app.get('/users/:id', ...);
|
|
325
|
-
app.get('/users/:userId', ...); // Same as above!
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
### ✅ DO: Use consistent naming
|
|
329
|
-
|
|
330
|
-
```typescript
|
|
331
|
-
// Good
|
|
332
|
-
app.get('/users/:userId', ...);
|
|
333
|
-
app.get('/users/:userId/posts/:postId', ...);
|
|
334
|
-
|
|
335
|
-
// Inconsistent
|
|
336
|
-
app.get('/users/:id', ...);
|
|
337
|
-
app.get('/users/:userId/posts/:pid', ...);
|
|
338
|
-
```
|
|
339
|
-
|
|
340
|
-
## Performance
|
|
341
|
-
|
|
342
|
-
### Route Matching
|
|
343
|
-
|
|
344
|
-
Nexus uses a **Radix Tree** for O(log n) route lookup:
|
|
345
|
-
|
|
346
|
-
```typescript
|
|
347
|
-
// Fast - even with 1000+ routes
|
|
348
|
-
app.get('/api/v1/users/:id', ...);
|
|
349
|
-
// Lookup time: ~0.001ms
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
### Route Compilation
|
|
353
|
-
|
|
354
|
-
Routes are compiled at startup for optimal performance:
|
|
355
|
-
|
|
356
|
-
```typescript
|
|
357
|
-
const app = createApp({
|
|
358
|
-
enableJIT: true // Enable JIT compilation (default)
|
|
359
|
-
});
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
## Advanced Patterns
|
|
363
|
-
|
|
364
|
-
### Optional Parameters
|
|
365
|
-
|
|
366
|
-
Use query parameters for optional data:
|
|
367
|
-
|
|
368
|
-
```typescript
|
|
369
|
-
// GET /users?role=admin&active=true
|
|
370
|
-
app.get('/users', async (ctx) => {
|
|
371
|
-
const filters = {
|
|
372
|
-
role: ctx.query.role,
|
|
373
|
-
active: ctx.query.active === 'true'
|
|
374
|
-
};
|
|
375
|
-
return await getUsers(filters);
|
|
376
|
-
});
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
### File Extensions
|
|
380
|
-
|
|
381
|
-
```typescript
|
|
382
|
-
app.get('/download/:filename', async (ctx) => {
|
|
383
|
-
const filename = ctx.params.filename;
|
|
384
|
-
// filename includes extension: "document.pdf"
|
|
385
|
-
return ctx.stream(createReadStream(filename));
|
|
386
|
-
});
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
## Next Steps
|
|
390
|
-
|
|
391
|
-
- ✅ [Schema Validation](./05-validation.md) - Validate route parameters
|
|
392
|
-
- 🔌 [Middleware](./04-middleware.md) - Add route-specific middleware
|
|
393
|
-
- 🔒 [Error Handling](./06-error-handling.md) - Handle route errors
|
|
394
|
-
|
|
395
|
-
---
|
|
396
|
-
|
|
397
|
-
[← Context API](./02-context.md) | [Middleware →](./04-middleware.md)
|