Skip to content

Commit

Permalink
feat(backend): add custom healthcheck package (#13)
Browse files Browse the repository at this point in the history
Signed-off-by: Dirk de Visser <[email protected]>
  • Loading branch information
dirkdev98 authored Feb 16, 2024
1 parent 9c5f009 commit c1f784d
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 22 deletions.
3 changes: 3 additions & 0 deletions apps/backend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,8 @@ npm run test
- Pretty logs in development with [pino-pretty](https://npm.im/pino-pretty).
- Graceful shutdown on exit signals via
[close-with-grace](https://npm.im/close-with-grace).
- Health checks via
[fastify-custom-healthcheck](https://npm.im/fastify-custom-healthcheck) allowing other
plugins to add custom health checks.
- Basic multipart form handling via
[@fastify/multipart](https://npm.im/@fastify/multipart).
26 changes: 9 additions & 17 deletions apps/backend/app.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import { Multipart } from "@fastify/multipart";
import fastify, { FastifyRequest } from "fastify";
import fastify, { FastifyBaseLogger, FastifyHttpOptions, FastifyRequest } from "fastify";
import * as http from "node:http";
import { basePlugin } from "./plugins/base.js";

export async function buildApp() {
const loggerConfig =
process.env.NODE_ENV === "development" ?
{
transport: {
target: "pino-pretty",
options: {
ignore: "pid,hostname",
},
},
}
: true;

const app = fastify({
logger: loggerConfig,
});
export async function buildApp(opts: FastifyHttpOptions<http.Server> = {}) {
const app = fastify<
http.Server,
http.IncomingMessage,
http.ServerResponse,
FastifyBaseLogger
>(opts);

app.register(basePlugin);

Expand Down
1 change: 1 addition & 0 deletions apps/backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"close-with-grace": "^1.2.0",
"dotenv": "^16.4.4",
"fastify": "^4.26.0",
"fastify-custom-healthcheck": "^3.1.0",
"fastify-plugin": "^4.5.1",
"@fastify/multipart": "^8.1.0"
},
Expand Down
24 changes: 23 additions & 1 deletion apps/backend/plugins/base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ test("base", async (t) => {
});

const data = await response.json();
console.log(data);

assert.equal(response.status, 200);
assert.deepEqual(data, [
Expand All @@ -39,4 +38,27 @@ test("base", async (t) => {
},
]);
});

await t.test("health check", async (t) => {
await t.test("success", async (t) => {
const response = await app.inject({
method: "get",
path: "/health",
});

assert.equal(response.statusCode, 200);
assert.equal(response.json().healthChecks.label, "HEALTHY");
});

await t.test("fail", async (t) => {
app.addHealthCheck("label2", () => false, { value: true });
const response = await app.inject({
method: "get",
path: "/health",
});

assert.equal(response.statusCode, 500);
assert.equal(response.json().healthChecks.label2, "FAIL");
});
});
});
22 changes: 19 additions & 3 deletions apps/backend/plugins/base.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { FastifyInstance, FastifyRegisterOptions, RegisterOptions } from "fastify";
import fp from "fastify-plugin";
import fastifyMultipart, { FastifyMultipartBaseOptions } from "@fastify/multipart";
import { RegisterOptions } from "fastify";
import fastifyCustomHealthCheck from "fastify-custom-healthcheck";
import fp from "fastify-plugin";
import { FastifyBase } from "../types.js";

async function base(
fastify: FastifyInstance,
fastify: FastifyBase,
options: RegisterOptions & {
multipart?: FastifyMultipartBaseOptions;
},
Expand Down Expand Up @@ -41,6 +43,20 @@ async function base(

...options.multipart,
});

// TODO: Why do we need `as any` here?
fastify.register(fastifyCustomHealthCheck as any, {
// TODO: we should allow configuring one or multiple routes

path: "/health",
info: {},
});

fastify.ready(() => {
fastify.addHealthCheck("label", () => true, {
value: true,
});
});
}

export const basePlugin = fp(base, {
Expand Down
16 changes: 15 additions & 1 deletion apps/backend/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,21 @@ import dotenv from "dotenv";

dotenv.config({ path: [".env.local", ".env"] });

const app = await buildApp();
const loggerConfig =
process.env.NODE_ENV === "development" ?
{
transport: {
target: "pino-pretty",
options: {
ignore: "pid,hostname",
},
},
}
: true;

const app = await buildApp({
logger: loggerConfig,
});

const closeGracefully = closeWithGrace({ delay: 500 }, async (options) => {
if (options.err) {
Expand Down
9 changes: 9 additions & 0 deletions apps/backend/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { FastifyBaseLogger, FastifyInstance } from "fastify";
import http from "node:http";

export type FastifyBase = FastifyInstance<
http.Server,
http.IncomingMessage,
http.ServerResponse,
FastifyBaseLogger
>;

0 comments on commit c1f784d

Please sign in to comment.