How to establish a database/broker connection only once in a NodeJS application
Singleton pattern usage with modules
Problem: We want to make connection to a database only once throughout our application.
We have a simple express api which does the following:
- Upon GET /cars request, new connection is going to be made to our fake database which will take five seconds. (line 20)
- After connection is established, cars will be queried from the database, which will take another five seconds. (line 21)
Each request handling will create a new connection to database which is going to be cumbersome. This might even lead to failures on database.
Solution: Modules are already singleton objects in NodeJS which means, an imported module file will be executed only once and will be referenced later.
Lets start with exporting our fake database to another file.
index.js
connectToFakeDatabase.js
Much cleaner isn’t it? But our problem is still there. And solution is really simple. We will follow these steps:
- Transform function declaration connectToFakeDatabase into function expression. (Line 1)
2. Immediately invoke it! (Line 13)
3. Now we have a problem. Whenever the first time our connectToFakeDatabase.js file gets imported, whole file will be executed and a promise will be exported.
It is close to what we need since this execution will happen once, but we need a function rather than a promise or a value.
Solution is to wrap the result in a function, and then export it. (Line 15)
So what will actually happen now;
- Whenever our API starts, it will import connectToFakeDatabase.js file.
- It will execute whatever we have in that file, then, will export.
- Remember, even if we import the connectToFakeDatabase.js file from multiple locations, they will all have the same memory reference.
- Now whenever GET /cars request has been made, all handlers will use imported the same reference (which is a function that returns the resolved connection)
This is a common way to initiate Promises once and export it throughout your application. You can use it for Database connections, Broker connections or even WebsocketAPI connections.
This solution (singleton pattern) can be both implied for CommonJS and ES6 Modules.
Have fun with your optimized app :)