Overview
I am attempting to learn Node JS with Express by creating a project.
I have seen many examples of setting up an express.js application with functional based programming, like so:
// app.js
"use strict";
const express = require("express");
const path = require("path");
const mongoose = require("mongoose");
const router = require("./routes/index");
const config = require("../config/config");
const app = express();
// Connect to the database.
let dbUser = encodeURIComponent(config.db.username);
let dbPass = encodeURIComponent(config.db.password);
let dbDatabase = encodeURIComponent(config.db.database);
let mongoUri = `mongodb://${dbUser}:${dbPass}@${config.db.host}:${config.db.port}/${dbDatabase}`;
mongoose.connect(mongoUri, { useNewUrlParser: true });
app.use(router); // Use the router location.
// Set up the views.
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
app.use(express.static(path.join(__dirname, "public"))); // Set the static file location.
app.listen(config.server.port); // Start the application on specified port.
Code
Below is the OOP code I have implemented to initialize the express application. The entire project can be found here: https://github.com/youkergav/MagicConchShellBot
Please note: While many techniques used in this project are overkill, the overall objective was to better learn Node JS. For all of my questions, please take them as if this were a large scale project, rather than the actual project size.
App File
// app.js
"use strict";
const express = require("express");
const Server = require("./lib/server");
let server = new Server;
server.initDb(); // Connect to the database.
server.initRoutes(); // Use the router location.
server.initViews(); // Set up the server views.
server.run();
Sever File
// lib/server.js
"use strict";
class Server {
constructor(express) {
this.express = express;
this.app = this.express();
this.config = require("../../config/config");
}
initDb() {
const Database = require("./database");
let database = new Database();
database.connect();
}
initRoutes() {
const Route = require("./route");
const route = new Route(this.app);
route.setRoute("../routes/general");
return true;
}
initViews() {
const View = require("./view");
const view = new View(this.express, this.app);
view.setViewsLocation("../views");
view.setViewEngine("ejs");
view.setStaticLocation("../public");
return true;
}
run() {
this.app.listen(this.config.server.port);
}
}
module.exports = Server;
Database File
// lib/database.js
"use strict";
class Database {
constructor() {
this.mongoose = require("mongoose");
this.config = require("../../config/config");
}
connect() {
let dbUser = encodeURIComponent(this.config.db.username);
let dbPass = encodeURIComponent(this.config.db.password);
let dbHost = this.config.db.host;
let dbPort = this.config.db.port;
let dbDatabase = encodeURIComponent(this.config.db.database);
let mongoUri = `mongodb://${dbUser}:${dbPass}@${dbHost}:${dbPort}/${dbDatabase}`;
this.mongoose.connect(mongoUri, { useNewUrlParser: true }, function(error) {
if(error) {
console.error(error);
return false;
}
return true;
});
}
disconnect() {
this.mongoose.connection.close(function(error) {
if(error) {
console.error(error);
return false;
}
return true;
});
}
}
module.exports = Database;
Route File
// lib/route.js
"use strict";
class Routes {
constructor(app) {
this.app = app;
}
setRoute(location) {
let route = require(location);
this.app.use(route);
return true;
}
}
module.exports = Routes;
View File
// lib/view.js
"use strict";
class Views {
constructor(express, app) {
this.express = express;
this.app = app;
this.path = require("path");
}
setViewsLocation(location) {
let fullLocation = this.path.join(__dirname, location);
this.app.set("views", fullLocation);
return true;
}
setViewEngine(engine) {
this.app.set("view engine", engine);
return true;
}
setStaticLocation(location) {
let fullLocation = this.path.join(__dirname, location);
let staticLocation = this.express.static(fullLocation);
this.app.use(staticLocation);
return true;
}
}
module.exports = Views;
Questions
I am uncertain if I should be using OOP here. Here are my thoughts and questions...
Pros:
- Scalable application: What are some common JS scalability issues? Is this an adequate solution?
- Cleaner code: Does this implementation of OOP offer a more obvious way on how the code should function?
- Ability to implement JSDocs
- Ability to perform unit tests
Cons:
- JavaScript is a functional based language: What advantages does a functional implementation have to offer?
- Added a layer of complexity: In your opinion, is this code better abstracted, or did I just make it harder to understand?
- I have not found any online examples of initializing express applications with OOP. Are there disadvantages to using OOP that I am missing?