Skip to content

Terminus ​

Terminus is a package to adds graceful shutdown and Kubernetes readiness / liveliness checks for any HTTP applications. This tutorial will show you how to install and use Terminus with Ts.ED.

Installation ​

Before using terminus, we need to install the terminus module.

sh
npm install --save @godaddy/terminus @tsed/terminus
sh
yarn add @godaddy/terminus @tsed/terminus
sh
pnpm add @godaddy/terminus @tsed/terminus
sh
bun add @godaddy/terminus @tsed/terminus

Then import @tsed/terminus and add the following configuration in your Server.ts:

typescript
import {Configuration} from "@tsed/di";
import "@tsed/terminus"; // import terminus Ts.ED module
import {resolve} from "node:path";

@Configuration({
  terminus: {
    path: "/health"
    // ... see configuration
  }
})
export class Server {}

Options ​

terminus configuration options waiting the same option description in the official Terminus documentation here. The following the options are managed by the @tsed/terminus package:

  • healthChecks
  • onSignal
  • onSendFailureDuringShutdown
  • onShutdown
  • beforeShutdown
  • onSigterm
typescript
export type TerminusSettings = Omit<
  TerminusOptions,
  "healthChecks" | "onSignal" | "onSendFailureDuringShutdown" | "onShutdown" | "beforeShutdown" | "onSigterm"
>;

Usage ​

Readiness / liveliness checks ​

To create a readiness / liveliness checks use the @Health decorator.

ts
import {Health} from "@tsed/terminus";
import {Injectable, Inject} from "@tsed/di";

@Injectable()
class MongoCtrl {
  @Health("mongo")
  async check() {
    // Here check the mongo health
    return "ok";
  }
}

You can also create an HealthCheckError when an error appear during your check.

ts
import {Health} from "@tsed/terminus";
import {Injectable, Inject} from "@tsed/di";
import {HealthCheckError} from "@godaddy/terminus";
import {REDIS_CONNECTION} from "./RedisConnection";

@Injectable()
class RedisClient {
  @Inject(REDIS_CONNECTION)
  protected redisConnection: REDIS_CONNECTION;

  @Health("redis")
  async check() {
    if (this.redisConnection.status === "ready") {
      return "ok";
    }

    // Here check the redis health
    throw new HealthCheckError("failed", {
      redis: this.redisConnection.status
    });
  }
}

Expected result when calling the "/health":

json
{
  "status": "ok",
  "info": [
    {
      "mongo": "ok"
    },
    {
      "redis": "ok"
    }
  ],
  "details": [
    {
      "mongo": "ok"
    },
    {
      "redis": "ok"
    }
  ]
}

Graceful shutdown ​

@tsed/terminus package give some decorators to handle Terminus hooks. These hooks allow you to adds graceful shutdown. Here is the list of decorators:

  • $beforeShutdown: Use this hook if you deploy your application with Kubernetes (see more details here),
  • $onSignal: cleanup hook, returning a promise (used to be onSigterm),
  • $onShutdown: called right before exiting,
  • $onSendFailureDuringShutdown: called before sending each 503 during shutdowns.

Example:

typescript
import {Injectable} from "@tsed/di";

@Injectable()
class RedisCtrl {
  $beforeShutdown() {
    console.log("called before shutdown");
  }

  $onSignal() {
    console.log("called on signal");
  }

  $onShutdown() {
    console.log("called on shutdown");
  }

  $onSendFailureDuringShutdown() {
    console.log("on send failure during shutdown");
  }
}

Author ​

Maintainers ​

Released under the MIT License.