Преглед на файлове

introduce endpoints health and status

Richard Köhl преди 2 години
родител
ревизия
90a3445752

+ 1 - 0
.env.example

@@ -1,2 +1,3 @@
+APPLICATION_NAME="My Deno Application"
 VERSION=0.1.0
 GREETING="hello world!"

+ 5 - 1
src/interfaces/controllers/controller.class.ts

@@ -2,6 +2,10 @@ export default class Controller {
   constructor(
     public path: string,
     public method: string,
-    public handler: (req: Request) => Response | Promise<Response>,
+    public handler: (
+      req: Request,
+      headers: Record<string, string>,
+    ) => Response | Promise<Response>,
+    public headers: Record<string, string> = {},
   ) {}
 }

+ 31 - 0
src/interfaces/controllers/health.controller.ts

@@ -0,0 +1,31 @@
+import Controller from 'if/controllers/controller.class.ts';
+
+export default new Controller(
+  '/health',
+  'GET',
+  (req: Request, headers: Record<string, string>) => {
+    const url = new URL(req.url);
+    const started = Deno.env.get('STARTED');
+    let uptime = 0;
+    if (started) {
+      uptime = new Date().getTime() - new Date(started).getTime();
+    }
+    // const uptime = new Date().to - new Date(Deno.env.get("STARTED"));
+    const body = {
+      app: Deno.env.get('APPLICATION_NAME'),
+      version: Deno.env.get('VERSION'),
+      currentTime: new Date().toISOString(),
+      started,
+      uptime: uptime / 1000,
+      host: url.hostname,
+      status: 'healthy',
+    };
+
+    const response = new Response(JSON.stringify(body));
+    for (const [name, value] of Object.entries(headers)) {
+      response.headers.set(name, value);
+    }
+    return response;
+  },
+  { 'Content-Type': 'application/json' },
+);

+ 3 - 2
src/interfaces/controllers/index.ts

@@ -1,4 +1,5 @@
 import rootController from 'if/controllers/root.controller.ts';
-import notFoundController from 'if/controllers/not-found.controller.ts';
+import healthController from 'if/controllers/health.controller.ts';
+import metricsController from 'if/controllers/metrics.controller.ts';
 
-export default [rootController, notFoundController];
+export default [rootController, healthController, metricsController];

+ 16 - 0
src/interfaces/controllers/metrics.controller.ts

@@ -0,0 +1,16 @@
+import Controller from 'if/controllers/controller.class.ts';
+
+export default new Controller(
+  '/metrics',
+  'GET',
+  (_req: Request, headers: Record<string, string>) => {
+    const body = Deno.metrics();
+
+    const response = new Response(JSON.stringify(body));
+    for (const [name, value] of Object.entries(headers)) {
+      response.headers.set(name, value);
+    }
+    return response;
+  },
+  { 'Content-Type': 'application/json' },
+);

+ 0 - 9
src/interfaces/controllers/not-found.controller.ts

@@ -1,9 +0,0 @@
-import Controller from 'if/controllers/controller.class.ts';
-
-export default new Controller(
-  '*',
-  '*',
-  (_req: Request) => {
-    return new Response('Not Found', { status: 404 });
-  },
-);

+ 1 - 1
src/interfaces/router.ts

@@ -7,7 +7,7 @@ export const router = (req: Request) => {
       (controller.path === '*' || controller.path === url.pathname) &&
       (controller.method === '*' || controller.method === req.method)
     ) {
-      return controller.handler(req);
+      return controller.handler(req, controller.headers);
     }
   }
   return new Response('Not Found', { status: 404 });

+ 1 - 0
src/main.ts

@@ -2,5 +2,6 @@ import { serve } from './deps.ts';
 import { router } from 'if/router.ts';
 
 if (import.meta.main) {
+  Deno.env.set('STARTED', new Date().toISOString());
   serve(router, { port: 1993 });
 }