浏览代码

Server: Refactoring to WebHandler architecture; added no-cache headers on /server API route

Christian Kahlau 3 年之前
父节点
当前提交
c942d90261
共有 3 个文件被更改,包括 97 次插入54 次删除
  1. 69 0
      server/src/webhdl/server-api-handler.class.ts
  2. 25 0
      server/src/webhdl/web-handler.base.ts
  3. 3 54
      server/src/webserver.class.ts

+ 69 - 0
server/src/webhdl/server-api-handler.class.ts

@@ -0,0 +1,69 @@
+import { RouterOptions } from 'express';
+
+import { HttpStatusException } from '../../../common/lib/http-status.exception';
+
+import { Database } from '../database.class';
+import { WebHandler } from './web-handler.base';
+
+export class ServerAPIHandler extends WebHandler {
+  constructor(private db: Database, options?: RouterOptions) {
+    super(options);
+
+    this.router.use(this.avoidCache);
+
+    this.router.get('/server', async (req, res, next) => {
+      try {
+        const serverConfigs = await this.db.getAllServerConfigs();
+        res.send(serverConfigs);
+      } catch (err) {
+        next(err);
+      }
+    });
+
+    this.router.get('/server/:serverID/data/types', async (req, res, next) => {
+      try {
+        const serverID = Number(req.params.serverID);
+
+        if (Number.isNaN(serverID)) {
+          throw new HttpStatusException(`Not a valid server id: ${req.params.serverID}`, 400);
+        }
+
+        const serverDataTypes = await this.db.getServerDataTypes(serverID);
+        res.send(serverDataTypes);
+      } catch (err) {
+        next(err);
+      }
+    });
+
+    this.router.get('/server/:serverID/data', async (req, res, next) => {
+      try {
+        const serverID = Number(req.params.serverID);
+
+        if (Number.isNaN(serverID)) {
+          throw new HttpStatusException(`Not a valid server id: ${req.params.serverID}`, 400);
+        }
+
+        const qStart = (req.query.start || '').toString();
+        const qEnd = (req.query.end || '').toString();
+        const qType = (req.query.type || '').toString();
+
+        if (!qStart || !qEnd || !qType) throw new HttpStatusException("QueryParams 'type', 'start' and 'end' are mandatory.", 400);
+
+        const start = new Date(qStart);
+        const end = new Date(qEnd);
+        if ([start.toString(), end.toString()].includes('Invalid Date')) {
+          throw new HttpStatusException("QueryParams 'start' and 'end' must be parseable dates or unix epoch timestamps (ms).", 400);
+        }
+
+        const data = await this.db.queryServerData(serverID, qType, start, end);
+        res.send({
+          start,
+          end,
+          data
+        } as QueryResponse<ServerData>);
+      } catch (err) {
+        next(err);
+      }
+    });
+  }
+}

+ 25 - 0
server/src/webhdl/web-handler.base.ts

@@ -0,0 +1,25 @@
+import { NextFunction, Request, Response, Router, RouterOptions } from 'express';
+import moment from 'moment';
+
+export abstract class WebHandler {
+  private _router: Router;
+
+  constructor(options?: RouterOptions) {
+    this._router = Router(options);
+  }
+
+  public get router(): Router {
+    return this._router;
+  }
+
+  protected avoidCache = (req: Request, res: Response, next: NextFunction) => {
+    res.setHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT');
+    res.setHeader('Last-Modified', `${moment().format('ddd, DD MMM YYYY HH:mm:ss')} CEST`);
+    res.setHeader('Cache-Control', 'no-cache, max-age=0, must-revalidate, no-store');
+    res.setHeader('Pragma', 'no-cache');
+
+    next();
+  };
+
+  public static async destroy() {}
+}

+ 3 - 54
server/src/webserver.class.ts

@@ -4,6 +4,7 @@ import { HttpStatusException } from '../../common/lib/http-status.exception';
 import { Logger } from '../../common/util/logger.class';
 
 import { Database } from './database.class';
+import { ServerAPIHandler } from './webhdl/server-api-handler.class';
 
 export class Webserver {
   private app: Express;
@@ -11,60 +12,8 @@ export class Webserver {
   constructor(private port: number, private db: Database) {
     this.app = express();
 
-    this.app.get('/server', async (req, res, next) => {
-      try {
-        const serverConfigs = await this.db.getAllServerConfigs();
-        res.send(serverConfigs);
-      } catch (err) {
-        next(err);
-      }
-    });
-
-    this.app.get('/server/:serverID/data/types', async (req, res, next) => {
-      try {
-        const serverID = Number(req.params.serverID);
-
-        if (Number.isNaN(serverID)) {
-          throw new HttpStatusException(`Not a valid server id: ${req.params.serverID}`, 400);
-        }
-
-        const serverDataTypes = await this.db.getServerDataTypes(serverID);
-        res.send(serverDataTypes);
-      } catch (err) {
-        next(err);
-      }
-    });
-
-    this.app.get('/server/:serverID/data', async (req, res, next) => {
-      try {
-        const serverID = Number(req.params.serverID);
-
-        if (Number.isNaN(serverID)) {
-          throw new HttpStatusException(`Not a valid server id: ${req.params.serverID}`, 400);
-        }
-
-        const qStart = (req.query.start || '').toString();
-        const qEnd = (req.query.end || '').toString();
-        const qType = (req.query.type || '').toString();
-
-        if (!qStart || !qEnd || !qType) throw new HttpStatusException("QueryParams 'type', 'start' and 'end' are mandatory.", 400);
-
-        const start = new Date(qStart);
-        const end = new Date(qEnd);
-        if ([start.toString(), end.toString()].includes('Invalid Date')) {
-          throw new HttpStatusException("QueryParams 'start' and 'end' must be parseable dates or unix epoch timestamps (ms).", 400);
-        }
-
-        const data = await this.db.queryServerData(serverID, qType, start, end);
-        res.send({
-          start,
-          end,
-          data
-        } as QueryResponse<ServerData>);
-      } catch (err) {
-        next(err);
-      }
-    });
+    const serverApi = new ServerAPIHandler(db);
+    this.app.use('/server', serverApi.router);
 
     this.app.use('/', express.static(process.env.STATIC_DIR || 'public'));