Skip to content

Commit d11be73

Browse files
Merge branch 'feat/terminus-v11' of https://github.com/BrunnerLivio/docs.nestjs.com into BrunnerLivio-feat/terminus-v11
2 parents fd6c0f0 + 836bfe2 commit d11be73

File tree

2 files changed

+119
-18
lines changed

2 files changed

+119
-18
lines changed

content/migration.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,93 @@ Additionally, the `ignoreEnvVars` configuration option, which previously allowed
201201

202202
A new `skipProcessEnv` option has also been introduced. This option allows you to prevent the `ConfigService#get` method from accessing the `process.env` object entirely, which can be helpful when you want to restrict the service from reading environment variables directly.
203203

204+
#### Terminus module
205+
206+
If you are using the `TerminusModule` and have built your own custom health indicator, a new API has been introduced in version 11. The new `HealthIndicatorService` is designed to enhance the readability and testability of custom health indicators.
207+
208+
**Previous Approach**
209+
210+
Before version 11, a health indicator might have looked like this:
211+
212+
```typescript
213+
@Injectable()
214+
export class DogHealthIndicator extends HealthIndicator {
215+
constructor(private readonly httpService: HttpService) {
216+
super();
217+
}
218+
219+
private getBadboys() {
220+
return firstValueFrom(
221+
this.httpService.get<Dog[]>('https://example.com/dog').pipe(
222+
map((response) => response.data),
223+
map((dogs) => dogs.filter((dog) => dog.state === DogState.BAD_BOY)),
224+
),
225+
);
226+
}
227+
228+
async isHealthy(key: string) {
229+
try {
230+
const badboys = await this.getBadboys();
231+
const isHealthy = badboys.length === 0;
232+
233+
const result = this.getStatus(key, isHealthy, { badboys: badboys.length });
234+
235+
if (!isHealthy) {
236+
throw new HealthCheckError('Dog check failed', result);
237+
}
238+
239+
return result;
240+
} catch (error) {
241+
const result = this.getStatus(key, isHealthy);
242+
throw new HealthCheckError('Dog check failed', result);
243+
}
244+
}
245+
}
246+
```
247+
248+
**Updated Approach (NestJS Terminus v11)**
249+
250+
In version 11, it is recommended to use the new `HealthIndicatorService` API, which simplifies the implementation. Here's how the same health indicator can be implemented:
251+
252+
```typescript
253+
@Injectable()
254+
export class DogHealthIndicator {
255+
constructor(
256+
private readonly httpService: HttpService,
257+
// Inject the `HealthIndicatorService` provided by the `TerminusModule`
258+
private readonly healthIndicatorService: HealthIndicatorService,
259+
) {}
260+
261+
private getBadboys() { // ... }
262+
263+
async isHealthy(key: string) {
264+
// Start the health indicator check for the given key
265+
const indicator = this.healthIndicatorService.check(key);
266+
267+
try {
268+
const badboys = await this.getBadboys();
269+
270+
if (badboys.length === 0) {
271+
// Mark the indicator as "down" and add additional info to the response
272+
return indicator.down({ badboys: badboys.length });
273+
}
274+
275+
// Mark the health indicator as up
276+
return indicator.up();
277+
} catch (error) {
278+
return indicator.down('Unable to retrieve dogs');
279+
}
280+
}
281+
}
282+
```
283+
284+
**Key changes**
285+
286+
- The `HealthIndicatorService` replaces the older `HealthIndicator` and `HealthCheckError` classes, providing a cleaner API for health checks.
287+
- The `check` method allows easy state tracking (`up` or `down`) while supporting additional metadata to be included in health check responses.
288+
289+
> info **Info** Please note that the `HealthIndicator` and `HealthCheckError` classes have been marked as deprecated and are scheduled for removal in the next major release.
290+
204291
#### Node.js v16 no longer supported
205292
206293
Starting with NestJS 11, Node.js v16 is no longer supported, as it reached its end-of-life (EOL) on September 11, 2023. NestJS 11 now requires **Node.js v20 or higher**.

content/recipes/terminus.md

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -413,51 +413,62 @@ Let's get started by creating a service that will represent our custom indicator
413413
```typescript
414414
@@filename(dog.health)
415415
import { Injectable } from '@nestjs/common';
416-
import { HealthIndicator, HealthIndicatorResult, HealthCheckError } from '@nestjs/terminus';
416+
import { HealthIndicatorService } from '@nestjs/terminus';
417417

418418
export interface Dog {
419419
name: string;
420420
type: string;
421421
}
422422

423423
@Injectable()
424-
export class DogHealthIndicator extends HealthIndicator {
424+
export class DogHealthIndicator {
425+
constructor(
426+
private readonly healthIndicatorService: HealthIndicatorService
427+
) {}
428+
425429
private dogs: Dog[] = [
426430
{ name: 'Fido', type: 'goodboy' },
427431
{ name: 'Rex', type: 'badboy' },
428432
];
429433

430-
async isHealthy(key: string): Promise<HealthIndicatorResult> {
434+
async isHealthy(key: string){
435+
const indicator = this.healthIndicatorService.check(key);
431436
const badboys = this.dogs.filter(dog => dog.type === 'badboy');
432437
const isHealthy = badboys.length === 0;
433-
const result = this.getStatus(key, isHealthy, { badboys: badboys.length });
434438

435-
if (isHealthy) {
436-
return result;
439+
if (!isHealthy) {
440+
return indicator.down({ badboys: badboys.length });
437441
}
438-
throw new HealthCheckError('Dogcheck failed', result);
442+
443+
return indicator.up();
439444
}
440445
}
441446
@@switch
442447
import { Injectable } from '@nestjs/common';
443-
import { HealthCheckError } from '@godaddy/terminus';
448+
import { HealthIndicatorService } from '@nestjs/terminus';
444449

445450
@Injectable()
446-
export class DogHealthIndicator extends HealthIndicator {
447-
dogs = [
451+
@Dependencies(HealthIndicatorService)
452+
export class DogHealthIndicator {
453+
constructor(healthIndicatorService) {
454+
this.healthIndicatorService = healthIndicatorService;
455+
}
456+
457+
private dogs = [
448458
{ name: 'Fido', type: 'goodboy' },
449459
{ name: 'Rex', type: 'badboy' },
450460
];
451461

452-
async isHealthy(key) {
462+
async isHealthy(key){
463+
const indicator = this.healthIndicatorService.check(key);
453464
const badboys = this.dogs.filter(dog => dog.type === 'badboy');
454465
const isHealthy = badboys.length === 0;
455-
const result = this.getStatus(key, isHealthy, { badboys: badboys.length });
456466

457-
if (isHealthy) {
458-
return result;
467+
if (!isHealthy) {
468+
return indicator.down({ badboys: badboys.length });
459469
}
460-
throw new HealthCheckError('Dogcheck failed', result);
470+
471+
return indicator.up();
461472
}
462473
}
463474
```
@@ -512,9 +523,12 @@ import { DogHealthIndicator } from './dog.health';
512523
@Dependencies(HealthCheckService, DogHealthIndicator)
513524
export class HealthController {
514525
constructor(
515-
private health,
516-
private dogHealthIndicator
517-
) {}
526+
health,
527+
dogHealthIndicator
528+
) {
529+
this.health = health;
530+
this.dogHealthIndicator = dogHealthIndicator;
531+
}
518532

519533
@Get()
520534
@HealthCheck()

0 commit comments

Comments
 (0)