» Node.js: Build a REST API with Express » 2. Development » 2.7 Config File & Logs

Config File and Logs

...
const c = {
  app: {
    port: Number(port),
  },
  db: {
    fileName: "test.db",
    dsn: "mysql://test_user:test_pass@127.0.0.1:3306/lr_book?charset=utf8mb4",
  },
};
...

As you may have noticed, hard-coded config items are potential security breaches. And they're hard to change and control after being compiled and deployed.

That's why you need a separate config file.

Add config.json:

{
  "app": {
    "port": 8080
  },
  "db": {
    "file_name": "test.db",
    "dsn": "mysql://test_user:test_pass@127.0.0.1:3306/lr_book?charset=utf8mb4"
  }
}

Add parseConfig function in infrastructure/config/config.ts:

@@ -1,3 +1,5 @@
+import { readFileSync } from "fs";
+
 interface DBConfig {
   fileName: string;
   dsn: string;
@@ -11,3 +13,7 @@ export interface Config {
   app: ApplicationConfig;
   db: DBConfig;
 }
+
+export function parseConfig(filename: string): Config {
+  return JSON.parse(readFileSync(filename, "utf-8"));
+}

Export it in infrastructure/config/index.ts:

export { Config, parseConfig } from "./config";

And use it in main.ts:

@@ -1,20 +1,13 @@
 import { WireHelper } from "@/application";
 import { InitApp } from "@/adapter/router";
+import { parseConfig } from "@/infrastructure/config";
 
-const port = process.env.PORT || 3000;
+const config_filename = "config.json";
 
-const c = {
-  app: {
-    port: Number(port),
-  },
-  db: {
-    fileName: "test.db",
-    dsn: "mysql://test_user:test_pass@127.0.0.1:3306/lr_book?charset=utf8mb4",
-  },
-};
+const c = parseConfig(config_filename);
 const wireHelper = new WireHelper(c);
 const app = InitApp(wireHelper);
 
-app.listen(port, () => {
-  console.log(`Running on port ${port}`);
+app.listen(c.app.port, () => {
+  console.log(`Running on port ${c.app.port}`);
 });

Hard-coded config items are moved into config.json. Nice!

Caution: Do not directly track your config.json file with Git, as this could potentially leak sensitive data. If necessary, only track the template of the configuration file.
e.g.

{
 "app": {
   "port": 3000
 },
 "db": {
   "file_name": "",
   "dsn": ""
 }
}

Morgan Logs

Morgan is a popular HTTP request logger middleware for Express.js. It helps you log incoming HTTP requests to your Express application.

First, install Morgan via npm:

npm i morgan

Also, you need to install @types/morgan to get access to the type definitions for Morgan.

npm install @types/morgan --save-dev

Use morgan in adapter/router.ts:

@@ -1,4 +1,5 @@
 import express, { Request, Response } from "express";
+import morgan from "morgan";
 
 import { Book } from "@/domain/model";
 import { BookOperator } from "@/application/executor";
@@ -105,6 +106,9 @@ export function InitApp(wireHelper: WireHelper): express.Express {
   // Middleware to parse JSON bodies
   app.use(express.json());
 
+  // Use Morgan middleware with predefined 'combined' format
+  app.use(morgan("combined"));
+
   // Define a health endpoint handler
   app.get("/", (req: Request, res: Response) => {
     res.status(200).json({ status: "ok" });

Then you can have nice logs like this:

::ffff:127.0.0.1 - - [01/Mar/2024:13:13:19 +0000] "GET /books HTTP/1.1" 200 483 "-" "curl/8.1.2"
::ffff:127.0.0.1 - - [01/Mar/2024:13:13:28 +0000] "GET /books/2 HTTP/1.1" 200 242 "-" "curl/8.1.2"