From 3b28862407fbe4c4c8ad10d358ab443220411339 Mon Sep 17 00:00:00 2001 From: Sebastian Wessel Date: Mon, 27 Feb 2023 16:38:57 +0000 Subject: [PATCH] feat: add /healthz endpoint to httpServer resolve #69 --- .../httpserver/src/HttpServerService.impl.ts | 15 ++++++++ .../httpserver/src/config/getDefaultConfig.ts | 1 + .../src/routes/openapi/getOpenApiJson.impl.ts | 38 ++++++++++++++++++- .../httpserver/src/types/HttpServerConfig.ts | 1 + 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/packages/httpserver/src/HttpServerService.impl.ts b/packages/httpserver/src/HttpServerService.impl.ts index 9124a1fa0..a5c438fed 100644 --- a/packages/httpserver/src/HttpServerService.impl.ts +++ b/packages/httpserver/src/HttpServerService.impl.ts @@ -161,6 +161,21 @@ export class HttpServerService extends Service { reply.send(new UnhandledError().getErrorResponse()) } }) + + if (this.config.enableHealthz) { + this.server.get('/healthz', async (_request, reply) => { + const isEventBridgeReady = await this.eventBridge.isReady() + + reply.header('content-type', 'application/json; charset=utf-8') + if (isEventBridgeReady) { + reply.status(StatusCode.OK) + reply.send(new HandledError(StatusCode.OK).getErrorResponse()) + return + } + reply.status(StatusCode.InternalServerError) + reply.send(new HandledError(StatusCode.InternalServerError).getErrorResponse()) + }) + } } addBeforeResponse(method: HTTPMethods, pattern: string, handler: BeforeResponseHook) { diff --git a/packages/httpserver/src/config/getDefaultConfig.ts b/packages/httpserver/src/config/getDefaultConfig.ts index 0fb4f3dce..31e508fe2 100644 --- a/packages/httpserver/src/config/getDefaultConfig.ts +++ b/packages/httpserver/src/config/getDefaultConfig.ts @@ -10,6 +10,7 @@ export const getDefaultConfig = (): HttpServerConfig => { domain: 'localhost', enableHelmet: true, enableCompress: true, + enableHealthz: true, enableCors: false, host: '', logLevel: 'warn', diff --git a/packages/httpserver/src/routes/openapi/getOpenApiJson.impl.ts b/packages/httpserver/src/routes/openapi/getOpenApiJson.impl.ts index 3df623099..e051bc48b 100644 --- a/packages/httpserver/src/routes/openapi/getOpenApiJson.impl.ts +++ b/packages/httpserver/src/routes/openapi/getOpenApiJson.impl.ts @@ -26,6 +26,7 @@ export const getOpenApiJson = function (this: HttpServerService) { const security = this.config.openApi?.security const externalDocs = this.config.openApi?.externalDocs const tags = this.config.openApi?.tags + const isHealthzEnabled = this.config.enableHealthz const logger = this.logger.getChildLogger({ serviceName: this.info.serviceName, @@ -51,6 +52,15 @@ export const getOpenApiJson = function (this: HttpServerService) { securitySchema = Object.keys(components.securitySchemes).map((name) => ({ [name]: [] })) } + const getErrorName = (code: StatusCode) => + StatusCode[code] + .replace(/[A-Z]/g, (letter) => ` ${letter}`) + .replace(/^./, (str) => { + return str.toUpperCase() + }) + .trim() + .replace(/^O K$/g, 'OK') + const getErrorResponseSchema = (code: StatusCode, message: string, schema?: SchemaObject) => { return { type: 'object', @@ -225,8 +235,6 @@ export const getOpenApiJson = function (this: HttpServerService) { const errorResponses: Record = {} - const getErrorName = (code: StatusCode) => StatusCode[code].replace(/[A-Z]/g, (letter) => ` ${letter}`) - if (definition.openApi?.inputPayload) { errorResponses[400] = { description: getErrorName(400), @@ -306,6 +314,32 @@ export const getOpenApiJson = function (this: HttpServerService) { } }) + if (isHealthzEnabled) { + json.paths['/healthz'] = { + get: { + description: 'indicates if the http server service is healthy', + responses: { + 200: { + description: 'http server service is up and running and successfully connected to event bridge', + content: { + 'application/json': { + schema: getErrorResponseSchema(200, getErrorName(200)), + }, + }, + }, + 500: { + description: 'http server service is not up and running or not successfully connected to event bridge', + content: { + 'application/json': { + schema: getErrorResponseSchema(500, getErrorName(500)), + }, + }, + }, + }, + }, + } + } + reply.header('content-type', 'application/json; charset=utf-8') return json } diff --git a/packages/httpserver/src/types/HttpServerConfig.ts b/packages/httpserver/src/types/HttpServerConfig.ts index a3c09707b..52c3e460f 100644 --- a/packages/httpserver/src/types/HttpServerConfig.ts +++ b/packages/httpserver/src/types/HttpServerConfig.ts @@ -23,6 +23,7 @@ export type HttpServerConfig = { cookieSecret?: string apiMountPath?: string enableHelmet?: boolean + enableHealthz?: boolean helmetOptions?: FastifyHelmetOptions enableCompress?: boolean compressOptions?: FastifyCompressOptions