@navios/core 0.4.0 → 0.5.1
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 +95 -2
- package/docs/README.md +310 -3
- package/docs/adapters.md +308 -0
- package/docs/application-setup.md +524 -0
- package/docs/attributes.md +689 -0
- package/docs/controllers.md +373 -0
- package/docs/endpoints.md +444 -0
- package/docs/exceptions.md +316 -0
- package/docs/guards.md +550 -0
- package/docs/modules.md +377 -0
- package/docs/quick-start.md +295 -0
- package/docs/services.md +427 -0
- package/docs/testing.md +704 -0
- package/lib/_tsup-dts-rollup.d.mts +310 -239
- package/lib/_tsup-dts-rollup.d.ts +310 -239
- package/lib/index.d.mts +51 -28
- package/lib/index.d.ts +51 -28
- package/lib/index.js +633 -1072
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +631 -1064
- package/lib/index.mjs.map +1 -1
- package/package.json +5 -9
- package/project.json +9 -1
- package/src/__tests__/config.service.spec.mts +11 -9
- package/src/__tests__/controller.spec.mts +0 -1
- package/src/config/config.service.mts +2 -2
- package/src/decorators/controller.decorator.mts +1 -1
- package/src/decorators/endpoint.decorator.mts +2 -2
- package/src/decorators/header.decorator.mts +1 -1
- package/src/decorators/multipart.decorator.mts +1 -2
- package/src/decorators/stream.decorator.mts +2 -3
- package/src/factories/endpoint-adapter.factory.mts +21 -0
- package/src/factories/http-adapter.factory.mts +20 -0
- package/src/factories/index.mts +6 -0
- package/src/factories/multipart-adapter.factory.mts +21 -0
- package/src/factories/reply.factory.mts +21 -0
- package/src/factories/request.factory.mts +21 -0
- package/src/factories/stream-adapter.factory.mts +20 -0
- package/src/index.mts +1 -1
- package/src/interfaces/abstract-execution-context.inteface.mts +13 -0
- package/src/interfaces/abstract-http-adapter.interface.mts +20 -0
- package/src/interfaces/abstract-http-cors-options.interface.mts +59 -0
- package/src/interfaces/abstract-http-handler-adapter.interface.mts +13 -0
- package/src/interfaces/abstract-http-listen-options.interface.mts +4 -0
- package/src/interfaces/can-activate.mts +4 -2
- package/src/interfaces/http-header.mts +18 -0
- package/src/interfaces/index.mts +6 -0
- package/src/logger/console-logger.service.mts +28 -44
- package/src/logger/index.mts +1 -2
- package/src/logger/logger.service.mts +9 -128
- package/src/logger/logger.tokens.mts +21 -0
- package/src/metadata/handler.metadata.mts +7 -5
- package/src/navios.application.mts +65 -172
- package/src/navios.environment.mts +30 -0
- package/src/navios.factory.mts +53 -12
- package/src/services/guard-runner.service.mts +19 -9
- package/src/services/index.mts +0 -2
- package/src/services/module-loader.service.mts +4 -3
- package/src/tokens/endpoint-adapter.token.mts +8 -0
- package/src/tokens/execution-context.token.mts +2 -2
- package/src/tokens/http-adapter.token.mts +8 -0
- package/src/tokens/index.mts +4 -1
- package/src/tokens/multipart-adapter.token.mts +8 -0
- package/src/tokens/reply.token.mts +1 -5
- package/src/tokens/request.token.mts +1 -7
- package/src/tokens/stream-adapter.token.mts +8 -0
- package/docs/recipes/prisma.md +0 -60
- package/e2e/endpoints/get.spec.mts +0 -97
- package/e2e/endpoints/post.spec.mts +0 -113
- package/examples/simple-test/api/index.mts +0 -64
- package/examples/simple-test/config/config.service.mts +0 -14
- package/examples/simple-test/config/configuration.mts +0 -7
- package/examples/simple-test/index.mts +0 -16
- package/examples/simple-test/src/acl/acl-modern.guard.mts +0 -15
- package/examples/simple-test/src/acl/acl.guard.mts +0 -14
- package/examples/simple-test/src/acl/app.guard.mts +0 -27
- package/examples/simple-test/src/acl/one-more.guard.mts +0 -15
- package/examples/simple-test/src/acl/public.attribute.mts +0 -21
- package/examples/simple-test/src/app.module.mts +0 -9
- package/examples/simple-test/src/user/user.controller.mts +0 -72
- package/examples/simple-test/src/user/user.module.mts +0 -14
- package/examples/simple-test/src/user/user.service.mts +0 -14
- package/src/adapters/endpoint-adapter.service.mts +0 -72
- package/src/adapters/handler-adapter.interface.mts +0 -21
- package/src/adapters/index.mts +0 -4
- package/src/adapters/multipart-adapter.service.mts +0 -135
- package/src/adapters/stream-adapter.service.mts +0 -91
- package/src/logger/logger.factory.mts +0 -36
- package/src/logger/pino-wrapper.mts +0 -64
- package/src/services/controller-adapter.service.mts +0 -124
- package/src/services/execution-context.mts +0 -54
- package/src/tokens/application.token.mts +0 -9
package/docs/modules.md
ADDED
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
# Modules
|
|
2
|
+
|
|
3
|
+
Modules in Navios are the primary building blocks for organizing your application. They provide a way to group related controllers, services, and other providers into cohesive units that can be easily managed and imported.
|
|
4
|
+
|
|
5
|
+
## What is a Module?
|
|
6
|
+
|
|
7
|
+
A module is a TypeScript class decorated with the `@Module()` decorator. It serves as a container for controllers, other modules, and shared guards. Modules help organize your application into logical boundaries and enable dependency injection across the application.
|
|
8
|
+
|
|
9
|
+
## Creating a Module
|
|
10
|
+
|
|
11
|
+
### Basic Module
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Module } from '@navios/core'
|
|
15
|
+
|
|
16
|
+
@Module()
|
|
17
|
+
export class AppModule {}
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### Module with Controllers
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { Module } from '@navios/core'
|
|
24
|
+
|
|
25
|
+
import { ProductController } from './product.controller'
|
|
26
|
+
import { UserController } from './user.controller'
|
|
27
|
+
|
|
28
|
+
@Module({
|
|
29
|
+
controllers: [UserController, ProductController],
|
|
30
|
+
})
|
|
31
|
+
export class AppModule {}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Module with Imports
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { Module } from '@navios/core'
|
|
38
|
+
|
|
39
|
+
import { AuthModule } from './auth/auth.module'
|
|
40
|
+
import { UserModule } from './user/user.module'
|
|
41
|
+
|
|
42
|
+
@Module({
|
|
43
|
+
imports: [UserModule, AuthModule],
|
|
44
|
+
})
|
|
45
|
+
export class AppModule {}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Module with Guards
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
import { Module } from '@navios/core'
|
|
52
|
+
|
|
53
|
+
import { AuthGuard } from './auth.guard'
|
|
54
|
+
import { UserController } from './user.controller'
|
|
55
|
+
|
|
56
|
+
@Module({
|
|
57
|
+
controllers: [UserController],
|
|
58
|
+
guards: [AuthGuard], // Applied to all controllers in this module
|
|
59
|
+
})
|
|
60
|
+
export class UserModule {}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Module Options
|
|
64
|
+
|
|
65
|
+
The `@Module()` decorator accepts the following options:
|
|
66
|
+
|
|
67
|
+
### `controllers`
|
|
68
|
+
|
|
69
|
+
- **Type**: `ClassType[] | Set<ClassType>`
|
|
70
|
+
- **Description**: Array of controller classes that belong to this module
|
|
71
|
+
- **Example**:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
@Module({
|
|
75
|
+
controllers: [UserController, PostController],
|
|
76
|
+
})
|
|
77
|
+
export class UserModule {}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### `imports`
|
|
81
|
+
|
|
82
|
+
- **Type**: `ClassType[] | Set<ClassType>`
|
|
83
|
+
- **Description**: Array of other modules to import into this module
|
|
84
|
+
- **Example**:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
@Module({
|
|
88
|
+
imports: [DatabaseModule, AuthModule],
|
|
89
|
+
})
|
|
90
|
+
export class AppModule {}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### `guards`
|
|
94
|
+
|
|
95
|
+
- **Type**: `ClassType[] | Set<ClassType>`
|
|
96
|
+
- **Description**: Array of guard classes that will be applied to all controllers in this module
|
|
97
|
+
- **Example**:
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
@Module({
|
|
101
|
+
guards: [AuthGuard, RoleGuard],
|
|
102
|
+
})
|
|
103
|
+
export class ProtectedModule {}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
## Module Lifecycle
|
|
107
|
+
|
|
108
|
+
Modules in Navios follow a specific lifecycle:
|
|
109
|
+
|
|
110
|
+
1. **Registration**: Modules are registered with the dependency injection container
|
|
111
|
+
2. **Import Resolution**: Imported modules are loaded recursively
|
|
112
|
+
3. **Controller Registration**: Controllers are registered and their endpoints discovered
|
|
113
|
+
4. **Guard Application**: Module-level guards are applied to all controllers
|
|
114
|
+
5. **Initialization**: Module initialization hooks are called
|
|
115
|
+
|
|
116
|
+
## Module Lifecycle Methods
|
|
117
|
+
|
|
118
|
+
### `onModuleInit`
|
|
119
|
+
|
|
120
|
+
The `onModuleInit` lifecycle method is called after the module has been initialized and all its dependencies have been resolved. This is useful for performing setup tasks, initializing connections, or running startup logic.
|
|
121
|
+
|
|
122
|
+
#### Interface
|
|
123
|
+
|
|
124
|
+
```typescript
|
|
125
|
+
interface NaviosModule {
|
|
126
|
+
onModuleInit(): void | Promise<void>
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
#### Usage
|
|
131
|
+
|
|
132
|
+
To use the `onModuleInit` lifecycle method, implement the `NaviosModule` interface in your module class:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
import { Module, NaviosModule } from '@navios/core'
|
|
136
|
+
|
|
137
|
+
@Module({
|
|
138
|
+
controllers: [UserController],
|
|
139
|
+
})
|
|
140
|
+
export class UserModule implements NaviosModule {
|
|
141
|
+
onModuleInit() {
|
|
142
|
+
console.log('UserModule has been initialized')
|
|
143
|
+
// Perform initialization logic here
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Async Initialization
|
|
149
|
+
|
|
150
|
+
The `onModuleInit` method can be asynchronous, allowing you to perform async setup tasks:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
import { Module, NaviosModule } from '@navios/core'
|
|
154
|
+
|
|
155
|
+
@Module({
|
|
156
|
+
controllers: [DatabaseController],
|
|
157
|
+
})
|
|
158
|
+
export class DatabaseModule implements NaviosModule {
|
|
159
|
+
async onModuleInit() {
|
|
160
|
+
console.log('Initializing database connection...')
|
|
161
|
+
await this.connectToDatabase()
|
|
162
|
+
console.log('Database connection established')
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private async connectToDatabase() {
|
|
166
|
+
// Database connection logic
|
|
167
|
+
return new Promise((resolve) => setTimeout(resolve, 1000))
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
#### Common Use Cases
|
|
173
|
+
|
|
174
|
+
- **Database Connections**: Initialize database connections or verify connectivity
|
|
175
|
+
- **Cache Warming**: Pre-populate caches with frequently accessed data
|
|
176
|
+
- **External Service Setup**: Initialize connections to external APIs or services
|
|
177
|
+
- **Configuration Validation**: Validate required configuration settings
|
|
178
|
+
- **Background Tasks**: Start background processes or scheduled tasks
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { Module, NaviosModule } from '@navios/core'
|
|
182
|
+
|
|
183
|
+
@Module({
|
|
184
|
+
controllers: [CacheController],
|
|
185
|
+
})
|
|
186
|
+
export class CacheModule implements NaviosModule {
|
|
187
|
+
private cache = new Map<string, any>()
|
|
188
|
+
|
|
189
|
+
async onModuleInit() {
|
|
190
|
+
// Warm up the cache with initial data
|
|
191
|
+
await this.warmUpCache()
|
|
192
|
+
|
|
193
|
+
// Validate configuration
|
|
194
|
+
this.validateConfiguration()
|
|
195
|
+
|
|
196
|
+
console.log('CacheModule initialized successfully')
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
private async warmUpCache() {
|
|
200
|
+
// Pre-populate cache with frequently accessed data
|
|
201
|
+
this.cache.set('app:config', await this.loadAppConfig())
|
|
202
|
+
this.cache.set('user:defaults', await this.loadUserDefaults())
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
private validateConfiguration() {
|
|
206
|
+
if (!process.env.CACHE_TTL) {
|
|
207
|
+
throw new Error('CACHE_TTL environment variable is required')
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private async loadAppConfig() {
|
|
212
|
+
// Load application configuration
|
|
213
|
+
return { theme: 'dark', language: 'en' }
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private async loadUserDefaults() {
|
|
217
|
+
// Load default user settings
|
|
218
|
+
return { notifications: true, theme: 'auto' }
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
#### Execution Order
|
|
224
|
+
|
|
225
|
+
The `onModuleInit` methods are called in dependency order:
|
|
226
|
+
|
|
227
|
+
1. **Imported modules first**: All imported modules' `onModuleInit` methods are called before the current module
|
|
228
|
+
2. **Current module last**: The current module's `onModuleInit` method is called after all its dependencies
|
|
229
|
+
|
|
230
|
+
```typescript
|
|
231
|
+
@Module({
|
|
232
|
+
imports: [DatabaseModule, CacheModule], // These initialize first
|
|
233
|
+
})
|
|
234
|
+
export class AppModule implements NaviosModule {
|
|
235
|
+
onModuleInit() {
|
|
236
|
+
// This runs after DatabaseModule and CacheModule have been initialized
|
|
237
|
+
console.log('AppModule initialized - all dependencies are ready')
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Module Metadata
|
|
243
|
+
|
|
244
|
+
Each module decorated with `@Module()` has associated metadata that Navios uses internally:
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
export interface ModuleMetadata {
|
|
248
|
+
controllers: Set<ClassType>
|
|
249
|
+
imports: Set<ClassType>
|
|
250
|
+
guards: Set<ClassType>
|
|
251
|
+
attributes: Map<symbol, unknown>
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Best Practices
|
|
256
|
+
|
|
257
|
+
### 1. Feature-Based Organization
|
|
258
|
+
|
|
259
|
+
Organize modules around business features rather than technical layers:
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// ✅ Good - Feature-based
|
|
263
|
+
@Module({
|
|
264
|
+
controllers: [UserController],
|
|
265
|
+
imports: [UserDatabaseModule],
|
|
266
|
+
})
|
|
267
|
+
export class UserModule {}
|
|
268
|
+
|
|
269
|
+
// ❌ Avoid - Layer-based
|
|
270
|
+
@Module({
|
|
271
|
+
controllers: [UserController, ProductController, OrderController],
|
|
272
|
+
})
|
|
273
|
+
export class ControllersModule {}
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### 2. Single Responsibility
|
|
277
|
+
|
|
278
|
+
Each module should have a single, well-defined responsibility:
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
// ✅ Good - Single responsibility
|
|
282
|
+
@Module({
|
|
283
|
+
controllers: [AuthController],
|
|
284
|
+
imports: [JwtModule],
|
|
285
|
+
})
|
|
286
|
+
export class AuthModule {}
|
|
287
|
+
|
|
288
|
+
// ❌ Avoid - Multiple responsibilities
|
|
289
|
+
@Module({
|
|
290
|
+
controllers: [AuthController, UserController, ProductController],
|
|
291
|
+
})
|
|
292
|
+
export class EverythingModule {}
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### 3. Explicit Dependencies
|
|
296
|
+
|
|
297
|
+
Always explicitly import the modules you depend on:
|
|
298
|
+
|
|
299
|
+
```typescript
|
|
300
|
+
// ✅ Good - Explicit imports
|
|
301
|
+
@Module({
|
|
302
|
+
imports: [AuthModule, DatabaseModule],
|
|
303
|
+
controllers: [UserController],
|
|
304
|
+
})
|
|
305
|
+
export class UserModule {}
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### 4. Module Composition
|
|
309
|
+
|
|
310
|
+
Build complex applications by composing smaller, focused modules:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
@Module({
|
|
314
|
+
imports: [AuthModule, UserModule, ProductModule, OrderModule],
|
|
315
|
+
})
|
|
316
|
+
export class AppModule {}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
## Advanced Usage
|
|
320
|
+
|
|
321
|
+
### Conditional Module Loading
|
|
322
|
+
|
|
323
|
+
You can conditionally include modules based on environment or configuration:
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
import { Module } from '@navios/core'
|
|
327
|
+
|
|
328
|
+
const imports = [CoreModule]
|
|
329
|
+
if (process.env.NODE_ENV === 'development') {
|
|
330
|
+
imports.push(DevToolsModule)
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
@Module({
|
|
334
|
+
imports,
|
|
335
|
+
controllers: [AppController],
|
|
336
|
+
})
|
|
337
|
+
export class AppModule {}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
### Module with Complex Guard Setup
|
|
341
|
+
|
|
342
|
+
```typescript
|
|
343
|
+
import { Module } from '@navios/core'
|
|
344
|
+
|
|
345
|
+
import { AuthGuard, RoleGuard, ThrottleGuard } from './guards'
|
|
346
|
+
|
|
347
|
+
@Module({
|
|
348
|
+
guards: [
|
|
349
|
+
AuthGuard, // Applied first
|
|
350
|
+
RoleGuard, // Applied second
|
|
351
|
+
ThrottleGuard, // Applied last
|
|
352
|
+
],
|
|
353
|
+
controllers: [AdminController],
|
|
354
|
+
})
|
|
355
|
+
export class AdminModule {}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Testing Modules
|
|
359
|
+
|
|
360
|
+
When testing modules, you can create test-specific module configurations:
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
import { Module } from '@navios/core'
|
|
364
|
+
|
|
365
|
+
import { MockUserService } from './mocks/user.service'
|
|
366
|
+
import { UserController } from './user.controller'
|
|
367
|
+
|
|
368
|
+
@Module({
|
|
369
|
+
controllers: [UserController],
|
|
370
|
+
// Use mock services for testing
|
|
371
|
+
})
|
|
372
|
+
export class TestUserModule {}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
## Module Discovery
|
|
376
|
+
|
|
377
|
+
Navios automatically discovers and registers modules through the module tree starting from your root application module.
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
|
|
3
|
+
This guide will help you get up and running with Navios quickly.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
Before starting, make sure you have:
|
|
8
|
+
|
|
9
|
+
- Node.js 18+ or Bun runtime
|
|
10
|
+
- TypeScript knowledge
|
|
11
|
+
- Basic understanding of HTTP APIs
|
|
12
|
+
|
|
13
|
+
## Step 1: Install Dependencies
|
|
14
|
+
|
|
15
|
+
Navios requires an HTTP adapter to function. Choose one based on your runtime:
|
|
16
|
+
|
|
17
|
+
### For Node.js (Fastify Adapter)
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @navios/core @navios/builder @navios/adapter-fastify zod fastify
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### For Bun Runtime (Bun Adapter)
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install @navios/core @navios/builder @navios/adapter-bun zod
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Step 2: Define Your API
|
|
30
|
+
|
|
31
|
+
Create a shared API definition file (`api/index.ts`):
|
|
32
|
+
|
|
33
|
+
```ts
|
|
34
|
+
import { builder } from '@navios/builder'
|
|
35
|
+
|
|
36
|
+
import { z } from 'zod'
|
|
37
|
+
|
|
38
|
+
export const api = builder({
|
|
39
|
+
useDiscriminatorResponse: true,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
export const createUserEndpoint = api.declareEndpoint({
|
|
43
|
+
method: 'post',
|
|
44
|
+
url: '/users',
|
|
45
|
+
requestSchema: z.object({
|
|
46
|
+
name: z.string().min(1),
|
|
47
|
+
email: z.string().email(),
|
|
48
|
+
}),
|
|
49
|
+
responseSchema: z.object({
|
|
50
|
+
id: z.string(),
|
|
51
|
+
name: z.string(),
|
|
52
|
+
email: z.string(),
|
|
53
|
+
createdAt: z.date(),
|
|
54
|
+
}),
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
export const getUserEndpoint = api.declareEndpoint({
|
|
58
|
+
method: 'get',
|
|
59
|
+
url: '/users/$id',
|
|
60
|
+
requestSchema: z.object({
|
|
61
|
+
id: z.string(),
|
|
62
|
+
}),
|
|
63
|
+
responseSchema: z.object({
|
|
64
|
+
id: z.string(),
|
|
65
|
+
name: z.string(),
|
|
66
|
+
email: z.string(),
|
|
67
|
+
createdAt: z.date(),
|
|
68
|
+
}),
|
|
69
|
+
})
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Step 3: Create a Service
|
|
73
|
+
|
|
74
|
+
Create a user service (`services/user.service.ts`):
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
import { Injectable } from '@navios/core'
|
|
78
|
+
|
|
79
|
+
export interface User {
|
|
80
|
+
id: string
|
|
81
|
+
name: string
|
|
82
|
+
email: string
|
|
83
|
+
createdAt: Date
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@Injectable()
|
|
87
|
+
export class UserService {
|
|
88
|
+
private users: User[] = []
|
|
89
|
+
private idCounter = 1
|
|
90
|
+
|
|
91
|
+
async createUser(name: string, email: string): Promise<User> {
|
|
92
|
+
const user: User = {
|
|
93
|
+
id: this.idCounter.toString(),
|
|
94
|
+
name,
|
|
95
|
+
email,
|
|
96
|
+
createdAt: new Date(),
|
|
97
|
+
}
|
|
98
|
+
this.users.push(user)
|
|
99
|
+
this.idCounter++
|
|
100
|
+
return user
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async getUserById(id: string): Promise<User | undefined> {
|
|
104
|
+
return this.users.find((user) => user.id === id)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
async getAllUsers(): Promise<User[]> {
|
|
108
|
+
return this.users
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Step 4: Create a Controller
|
|
114
|
+
|
|
115
|
+
Create a user controller (`controllers/user.controller.ts`):
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import type { EndpointParams } from '@navios/core'
|
|
119
|
+
|
|
120
|
+
import {
|
|
121
|
+
Controller,
|
|
122
|
+
Endpoint,
|
|
123
|
+
NotFoundException,
|
|
124
|
+
syncInject,
|
|
125
|
+
} from '@navios/core'
|
|
126
|
+
|
|
127
|
+
import { createUserEndpoint, getUserEndpoint } from '../api/index.js'
|
|
128
|
+
import { UserService } from '../services/user.service.js'
|
|
129
|
+
|
|
130
|
+
@Controller()
|
|
131
|
+
export class UserController {
|
|
132
|
+
private userService = syncInject(UserService)
|
|
133
|
+
|
|
134
|
+
@Endpoint(createUserEndpoint)
|
|
135
|
+
async createUser(request: EndpointParams<typeof createUserEndpoint>) {
|
|
136
|
+
const { name, email } = request
|
|
137
|
+
return await this.userService.createUser(name, email)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@Endpoint(getUserEndpoint)
|
|
141
|
+
async getUser(request: EndpointParams<typeof getUserEndpoint>) {
|
|
142
|
+
const { id } = request
|
|
143
|
+
const user = await this.userService.getUserById(id)
|
|
144
|
+
|
|
145
|
+
if (!user) {
|
|
146
|
+
throw new NotFoundException('User not found')
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return user
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Step 5: Create an App Module
|
|
155
|
+
|
|
156
|
+
Create your application module (`app.module.ts`):
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
import { Module } from '@navios/core'
|
|
160
|
+
|
|
161
|
+
import { UserController } from './controllers/user.controller.js'
|
|
162
|
+
import { UserService } from './services/user.service.js'
|
|
163
|
+
|
|
164
|
+
@Module({
|
|
165
|
+
controllers: [UserController],
|
|
166
|
+
providers: [UserService],
|
|
167
|
+
})
|
|
168
|
+
export class AppModule {}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Step 6: Create the Server
|
|
172
|
+
|
|
173
|
+
Create your server entry point (`server.ts`):
|
|
174
|
+
|
|
175
|
+
### Using Fastify Adapter (Node.js)
|
|
176
|
+
|
|
177
|
+
```ts
|
|
178
|
+
import { defineFastifyEnvironment } from '@navios/adapter-fastify'
|
|
179
|
+
import { NaviosFactory } from '@navios/core'
|
|
180
|
+
|
|
181
|
+
import { AppModule } from './app.module.js'
|
|
182
|
+
|
|
183
|
+
async function bootstrap() {
|
|
184
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
185
|
+
adapter: defineFastifyEnvironment(), // Required!
|
|
186
|
+
})
|
|
187
|
+
|
|
188
|
+
// Optional: Configure CORS
|
|
189
|
+
app.enableCors({
|
|
190
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
// Optional: Set global prefix
|
|
194
|
+
app.setGlobalPrefix('/api')
|
|
195
|
+
|
|
196
|
+
await app.init()
|
|
197
|
+
await app.listen({ port: 3000, host: '0.0.0.0' })
|
|
198
|
+
|
|
199
|
+
console.log('Server running on http://localhost:3000')
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
bootstrap().catch(console.error)
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Using Bun Adapter (Bun Runtime)
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
import { defineBunEnvironment } from '@navios/adapter-bun'
|
|
209
|
+
import { NaviosFactory } from '@navios/core'
|
|
210
|
+
|
|
211
|
+
import { AppModule } from './app.module.js'
|
|
212
|
+
|
|
213
|
+
async function bootstrap() {
|
|
214
|
+
const app = await NaviosFactory.create(AppModule, {
|
|
215
|
+
adapter: defineBunEnvironment(), // Required!
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
// Optional: Configure CORS
|
|
219
|
+
app.enableCors({
|
|
220
|
+
methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS'],
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
// Optional: Set global prefix
|
|
224
|
+
app.setGlobalPrefix('/api')
|
|
225
|
+
|
|
226
|
+
await app.init()
|
|
227
|
+
await app.listen({ port: 3000, host: '0.0.0.0' })
|
|
228
|
+
|
|
229
|
+
console.log('Server running on http://localhost:3000')
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
bootstrap().catch(console.error)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Step 7: Run Your Server
|
|
236
|
+
|
|
237
|
+
### With Node.js
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
npx tsx server.ts
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### With Bun
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
bun run server.ts
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Step 8: Test Your API
|
|
250
|
+
|
|
251
|
+
Your server is now running! Test the endpoints:
|
|
252
|
+
|
|
253
|
+
### Create a user
|
|
254
|
+
|
|
255
|
+
```bash
|
|
256
|
+
curl -X POST http://localhost:3000/api/users \
|
|
257
|
+
-H "Content-Type: application/json" \
|
|
258
|
+
-d '{"name": "John Doe", "email": "john@example.com"}'
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Get a user
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
curl http://localhost:3000/api/users/1
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Next Steps
|
|
268
|
+
|
|
269
|
+
Now that you have a basic Navios server running:
|
|
270
|
+
|
|
271
|
+
1. **Add more endpoints** - Extend your API definition
|
|
272
|
+
2. **Add authentication** - Use guards for protecting endpoints
|
|
273
|
+
3. **Add validation** - Leverage Zod schemas for complex validation
|
|
274
|
+
4. **Add database integration** - Connect to your preferred database
|
|
275
|
+
5. **Add error handling** - Use Navios exceptions for consistent error responses
|
|
276
|
+
6. **Add testing** - Write unit and integration tests for your API
|
|
277
|
+
|
|
278
|
+
## Common Gotchas
|
|
279
|
+
|
|
280
|
+
1. **Missing Adapter**: The most common error is forgetting to install and configure an adapter. Navios will not work without one!
|
|
281
|
+
|
|
282
|
+
2. **Import Paths**: Make sure to use the correct file extensions (`.js` or `.mjs`) in your imports for TypeScript compilation.
|
|
283
|
+
|
|
284
|
+
3. **Async/Await**: Remember to use `async/await` in your endpoint handlers for proper error handling.
|
|
285
|
+
|
|
286
|
+
4. **Type Safety**: Leverage TypeScript fully by using the provided types from Navios.
|
|
287
|
+
|
|
288
|
+
## Help and Resources
|
|
289
|
+
|
|
290
|
+
- [Full Documentation](./README.md)
|
|
291
|
+
- [Adapter Guide](./adapters.md)
|
|
292
|
+
- [GitHub Repository](https://github.com/Arilas/navios)
|
|
293
|
+
- [Examples](../../examples/)
|
|
294
|
+
|
|
295
|
+
Happy coding with Navios! 🚀
|