Creating a basic interface pattern in NodeJS

The interface pattern is rarely understood and almost never used in JavaScript. On a large project or in a big team, interfaces provide a critical abstraction and the maintaining and use of them is something that Architects or Lead will focus on as a tool to keep code quality known and functionality expected. JavaScript does not yet have this basic functionality as it’s not an Object Oriented Programming language. Instead, it leans and most code in the wild is leaning, toward the Functional Programming behaviors of JavaScript. Interface patterns are still useful and it’s fairly easy to created something in JavaScript that contains the proper abstractions to benefit the code that helps a project.

Let’s begin with the ‘why’. The need to interface patterns, as stated above, may come from technical leads as a tool to form the code to what they expect to be common. More formally, interfaces provide a blueprint to a common API between two code bases. A few better definitions can be found on Stack Overflow. Interfaces are the abstraction of the structure of a class, not the definition of. Using them ‘guarantees’ the object will contain the interface requirements. Many places in code, especially in JavaScript, undefined checks are required. LoDash’s get method is one great method that makes this for the code in a common pattern. These checks bleed into software and make changing the software hard.

“Do we have this method and if so, use it”.
“Does the data contain this object, else give an empty array”.

If the structure of the data or object change, these safeguards must all be updated. Worse still, they can not be added and the page may error out. Interface pattern is one of the best tools to counter this. A not so hard to use example is taking advantage of the extends property in classes. In this case we want to create a Menu, but we want to make sure that all of our Menu’s have the same method to get the items. Each menu however will have their own items and we will write many tests assuming the getItems exist. We must make sure all menu’s have this method, else we have to safeguard within all uses.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// MenuInterface.js
class MenuInterface {
constructor() {
if(!this.getItems) {
throw new Error("Menu's must have items!");
}
}
}

// ---

// file index.js
import MenuInterface from './MenuInterface';

class Menu extends MenuInterface {
// no items
}
export default new Menu() // Error "Menu's must have items!"


// ---

// file baseMenu.js
class BaseMenu extends MenuInterface {
constructor() {
super();
this.items = [];
}
get getItems() {
return items;
}
}
export default new BaseMenu(); // No Error, has the method!

In a way, we have provided a ‘forced structure’ of the Menu. This is the basic interface pattern that solves one of those major issues of safeguarding. We know that baseMenu.getItems() will exist and not fail. Further, we can use flow or typescript to guarantee the return types on the methods. More JavaScript engineers should take advantage of the patterns, like interfaces, that provide proven abstractions to problems being solved. They free the code and the developer to think about the logic, not every little implementation detail by positioning the behaviors of the code into well organized and easily understood logic.