0
# Application Container
1
2
The Application class is the central container for LoopBack 4 applications, extending Context to provide a complete IoC container with lifecycle management. It serves as the main entry point for registering components, servers, controllers, and services.
3
4
## Capabilities
5
6
### Application Constructor
7
8
Creates a new Application instance with optional configuration and parent context.
9
10
```typescript { .api }
11
/**
12
* Create an application with the given parent context
13
*/
14
constructor(parent: Context);
15
16
/**
17
* Create an application with the given configuration and parent context
18
*/
19
constructor(config?: ApplicationConfig, parent?: Context);
20
```
21
22
**Usage Examples:**
23
24
```typescript
25
import { Application } from "@loopback/core";
26
27
// Basic application
28
const app = new Application();
29
30
// Application with configuration
31
const app = new Application({
32
name: 'my-service',
33
shutdown: {
34
signals: ['SIGTERM', 'SIGINT'],
35
gracePeriod: 5000
36
}
37
});
38
39
// Application with parent context
40
const parentContext = new Context();
41
const app = new Application(parentContext);
42
43
// Application with both config and parent
44
const app = new Application({
45
name: 'child-service'
46
}, parentContext);
47
```
48
49
### Component Registration
50
51
Register components that contribute controllers, providers, servers, and other resources to the application.
52
53
```typescript { .api }
54
/**
55
* Add a component to this application and register extensions such as
56
* controllers, providers, and servers from the component.
57
*/
58
component<T extends Component = Component>(
59
componentCtor: Constructor<T>,
60
nameOrOptions?: string | BindingFromClassOptions
61
): Binding<T>;
62
```
63
64
**Usage Examples:**
65
66
```typescript
67
import { Application, Component } from "@loopback/core";
68
69
class ProductComponent implements Component {
70
controllers = [ProductController];
71
repositories = [ProductRepository];
72
providers = {
73
'services.productService': ProductServiceProvider
74
};
75
}
76
77
// Register the component
78
const app = new Application();
79
app.component(ProductComponent);
80
81
// Register with custom name
82
app.component(ProductComponent, 'products');
83
84
// Register with options
85
app.component(ProductComponent, {
86
name: 'product-component',
87
namespace: 'products'
88
});
89
```
90
91
### Server Management
92
93
Register and manage server instances for handling different protocols (REST, GraphQL, gRPC, etc.).
94
95
```typescript { .api }
96
/**
97
* Bind a Server constructor to the Application's master context.
98
* Each server constructor added in this way must provide a unique prefix
99
* to prevent binding overlap.
100
*/
101
server<T extends Server>(
102
ctor: Constructor<T>,
103
nameOrOptions?: string | BindingFromClassOptions
104
): Binding<T>;
105
106
/**
107
* Bind an array of Server constructors to the Application's master context.
108
*/
109
servers<T extends Server>(ctors: Constructor<T>[]): Binding[];
110
111
/**
112
* Retrieve the singleton instance for a bound server.
113
*/
114
getServer<T extends Server>(target: Constructor<T> | string): Promise<T>;
115
```
116
117
**Usage Examples:**
118
119
```typescript
120
import { Application, Server } from "@loopback/core";
121
122
class RestServer implements Server {
123
listening = false;
124
125
async start(): Promise<void> {
126
// Start REST server logic
127
this.listening = true;
128
}
129
130
async stop(): Promise<void> {
131
// Stop REST server logic
132
this.listening = false;
133
}
134
}
135
136
const app = new Application();
137
138
// Register single server
139
app.server(RestServer);
140
141
// Register with custom name
142
app.server(RestServer, 'api-server');
143
144
// Register multiple servers
145
app.servers([RestServer, GraphQLServer]);
146
147
// Retrieve server instance
148
const restServer = await app.getServer(RestServer);
149
const namedServer = await app.getServer('api-server');
150
```
151
152
### Controller Registration
153
154
Register controller classes that handle HTTP requests and other application logic.
155
156
```typescript { .api }
157
/**
158
* Register a controller class with this application.
159
*/
160
controller<T>(
161
controllerCtor: ControllerClass<T>,
162
nameOrOptions?: string | BindingFromClassOptions
163
): Binding<T>;
164
```
165
166
**Usage Examples:**
167
168
```typescript
169
import { Application } from "@loopback/core";
170
171
class UserController {
172
async getUsers(): Promise<User[]> {
173
// Controller logic
174
return [];
175
}
176
}
177
178
const app = new Application();
179
180
// Register controller
181
app.controller(UserController);
182
183
// Register with custom name
184
app.controller(UserController, 'users');
185
186
// Register with options
187
app.controller(UserController, {
188
name: 'user-controller',
189
namespace: 'controllers'
190
});
191
```
192
193
### Service Registration
194
195
Register service classes and providers for dependency injection throughout the application.
196
197
```typescript { .api }
198
/**
199
* Add a service to this application.
200
*/
201
service<S>(
202
cls: ServiceOrProviderClass<S>,
203
nameOrOptions?: string | ServiceOptions
204
): Binding<S>;
205
```
206
207
**Usage Examples:**
208
209
```typescript
210
import { Application, service, Provider } from "@loopback/core";
211
212
// Service class
213
class EmailService {
214
async sendEmail(to: string, subject: string, body: string): Promise<void> {
215
// Email sending logic
216
}
217
}
218
219
// Provider class
220
class ConfigProvider implements Provider<AppConfig> {
221
value(): AppConfig {
222
return {
223
apiUrl: process.env.API_URL || 'http://localhost:3000'
224
};
225
}
226
}
227
228
const app = new Application();
229
230
// Register service class
231
app.service(EmailService);
232
233
// Register provider
234
app.service(ConfigProvider, 'config');
235
236
// Register with service interface
237
app.service(EmailService, {
238
interface: Symbol.for('EmailService')
239
});
240
```
241
242
### Lifecycle Management
243
244
Manage application lifecycle with coordinated initialization, start, and stop sequences.
245
246
```typescript { .api }
247
/**
248
* Initialize the application, and all of its registered observers.
249
*/
250
init(): Promise<void>;
251
252
/**
253
* Start the application, and all of its registered observers.
254
*/
255
start(): Promise<void>;
256
257
/**
258
* Stop the application instance and all of its registered observers.
259
*/
260
stop(): Promise<void>;
261
262
/**
263
* Register a function to be called when the application initializes.
264
*/
265
onInit(fn: () => ValueOrPromise<void>): Binding<LifeCycleObserver>;
266
267
/**
268
* Register a function to be called when the application starts.
269
*/
270
onStart(fn: () => ValueOrPromise<void>): Binding<LifeCycleObserver>;
271
272
/**
273
* Register a function to be called when the application stops.
274
*/
275
onStop(fn: () => ValueOrPromise<void>): Binding<LifeCycleObserver>;
276
277
/**
278
* Get the state of the application.
279
*/
280
readonly state: string;
281
```
282
283
**Usage Examples:**
284
285
```typescript
286
import { Application } from "@loopback/core";
287
288
const app = new Application();
289
290
// Register lifecycle hooks
291
app.onInit(async () => {
292
console.log('Application is initializing...');
293
});
294
295
app.onStart(async () => {
296
console.log('Application is starting...');
297
});
298
299
app.onStop(async () => {
300
console.log('Application is stopping...');
301
});
302
303
// Manual lifecycle management
304
await app.init(); // State: 'initialized'
305
await app.start(); // State: 'started'
306
await app.stop(); // State: 'stopped'
307
308
// Check application state
309
console.log(app.state); // 'created', 'initialized', 'started', 'stopped', etc.
310
```
311
312
### Lifecycle Observer Registration
313
314
Register classes that implement the LifeCycleObserver interface for coordinated startup and shutdown.
315
316
```typescript { .api }
317
/**
318
* Register a life cycle observer class
319
*/
320
lifeCycleObserver<T extends LifeCycleObserver>(
321
ctor: Constructor<T>,
322
nameOrOptions?: string | BindingFromClassOptions
323
): Binding<T>;
324
```
325
326
**Usage Examples:**
327
328
```typescript
329
import { Application, LifeCycleObserver, lifeCycleObserver } from "@loopback/core";
330
331
@lifeCycleObserver('database')
332
class DatabaseObserver implements LifeCycleObserver {
333
async init(): Promise<void> {
334
console.log('Initializing database connection...');
335
}
336
337
async start(): Promise<void> {
338
console.log('Database connection started');
339
}
340
341
async stop(): Promise<void> {
342
console.log('Closing database connection...');
343
}
344
}
345
346
const app = new Application();
347
348
// Register lifecycle observer
349
app.lifeCycleObserver(DatabaseObserver);
350
351
// Register with custom name
352
app.lifeCycleObserver(DatabaseObserver, 'db-observer');
353
```
354
355
### Interceptor Registration
356
357
Register interceptors for aspect-oriented programming and cross-cutting concerns.
358
359
```typescript { .api }
360
/**
361
* Register an interceptor
362
*/
363
interceptor(
364
interceptor: Interceptor | Constructor<Provider<Interceptor>>,
365
nameOrOptions?: string | InterceptorBindingOptions
366
): Binding<Interceptor | Constructor<Provider<Interceptor>>>;
367
```
368
369
**Usage Examples:**
370
371
```typescript
372
import { Application, Interceptor, InterceptorBindingOptions } from "@loopback/core";
373
374
const loggingInterceptor: Interceptor = async (context, next) => {
375
console.log(`Calling method: ${context.methodName}`);
376
const result = await next();
377
console.log(`Method completed: ${context.methodName}`);
378
return result;
379
};
380
381
const app = new Application();
382
383
// Register interceptor function
384
app.interceptor(loggingInterceptor, 'logging');
385
386
// Register with options
387
app.interceptor(loggingInterceptor, {
388
name: 'request-logger',
389
global: true,
390
group: 'logging'
391
});
392
```
393
394
### Metadata Management
395
396
Set and manage application metadata from package.json or other sources.
397
398
```typescript { .api }
399
/**
400
* Set application metadata. @loopback/boot calls this method to populate
401
* the metadata from package.json.
402
*/
403
setMetadata(metadata: ApplicationMetadata): void;
404
```
405
406
**Usage Examples:**
407
408
```typescript
409
import { Application, ApplicationMetadata } from "@loopback/core";
410
411
const app = new Application();
412
413
const metadata: ApplicationMetadata = {
414
name: 'my-service',
415
version: '1.0.0',
416
description: 'A sample LoopBack application'
417
};
418
419
app.setMetadata(metadata);
420
```
421
422
## Types
423
424
```typescript { .api }
425
interface ApplicationConfig {
426
/** Name of the application context */
427
name?: string;
428
/** Configuration for signals that shut down the application */
429
shutdown?: ShutdownOptions;
430
/** Other properties */
431
[prop: string]: any;
432
}
433
434
interface ShutdownOptions {
435
/** An array of signals to be trapped for graceful shutdown */
436
signals?: NodeJS.Signals[];
437
/** Period in milliseconds to wait for the grace shutdown to finish */
438
gracePeriod?: number;
439
}
440
441
interface ApplicationMetadata extends JSONObject {
442
name: string;
443
version: string;
444
description: string;
445
}
446
447
type ControllerClass<T = any> = Constructor<T>;
448
449
type ServiceOrProviderClass<T = any> =
450
| Constructor<T | Provider<T>>
451
| DynamicValueProviderClass<T>;
452
453
interface Server extends LifeCycleObserver {
454
/** Tells whether the server is listening for connections or not */
455
readonly listening: boolean;
456
}
457
```