banner



How To Single Instance Service Node Js

Cover image for Singleton design pattern use case with Node.js (Typescript) + Express.js

TalR98

TalR98

Posted on • Updated on

Singleton design blueprint use case with Node.js (Typescript) + Express.js

Today I volition be introducing and using the Singleton Design Blueprint, using Node.js (with typescript) and Express library.

First, Why would I need Singelton?

Sometimes you need to make certain that you have one and only one example of an object. This is where the singleton pattern can exist useful. A singleton represents a single instance of an object. Only one can be created, no matter how many times the object is instantiated. If there's already an instance, the singleton will create a new one.

Let's take a look at some use cases that would exist nice to exist

Information technology is popular to utilise a database connection (like MongoDB) within a Node.js application. Just where and how you should instantiate that connectedness?

There are several ways to do it. You lot could just create a file dedicated for this connection that handles the connectedness for the database.

It is popular to use logger library such equally Winston. Where should you instantiate the logger and define it?

Again - you could create a dedicated file to handle this whole affair.

There are more use cases of grade, depends on your application. Merely we can already see - we have 2 dedicated files to manage. What if it would abound? What if you desire to have some logic with each? And then in my opinion the whole thing becomes complicated and makes your code dirty.

An optional solution

Utilize a primal singleton class for these global stuff to manage it in one place, well-organized.

So we are going to create simple server that connects to MongoDB and logs some text to the console & external file. For this I'm gonna exist using Typescript, because information technology makes the creation of the singleton class more than easy, and besides that, why non?

For this, let's create a file with arbitrary name: server-global.ts. So we know we volition exist using MongoDB and logging text. So let's install via npm the three packages: mongoose, @types/mongoose, winstion: npm i mongoose winston, npm i -D @types/winston.

So let'due south first build a simple grade ServerGlobal inside the file we created:

                          import              mongoose              from              '              mongoose              '              ;              import              winston              from              '              winston              '              ;              class              ServerGlobal              {              }              export              default              ServerGlobal              ;                      

Enter fullscreen manner Exit fullscreen manner

So what makes a course singleton? We should avoid creating more than ane instance of the form somehow. Making the form constructor to individual one would easily solve it - then you lot would not be able to instantiate the form at all exterior the class.

The problem is.. how the singleton instance is being created?
So making the constructor private, does not hateful yous cannot instantiate the class within the class:

                          import              mongoose              from              '              mongoose              '              ;              import              winston              from              '              winston              '              ;              class              ServerGlobal              {              individual              static              _instance              :              ServerGlobal              ;              private              constructor              ()              {              }              static              getInstance              ()              {              if              (              this              .              _instance              )              {              return              this              .              _instance              ;              }              this              .              _instance              =              new              ServerGlobal              ();              return              this              .              _instance              ;              }              }              export              default              ServerGlobal              ;                      

Enter fullscreen fashion Exit fullscreen mode

And so what happened here?

We manage the singleton instance within the class. Then we provide function, getInstance, to allow using the singleton outside the class. Both are static ones, because as I said - the form constructor is private. It means you cannot create instance of the class. And then, we demand to allow somehow get an case. For this we have the static.

We can already utilise the singleton now. If nosotros create a dummy file, we would get the singleton with the following code:

                          import              ServerGlobal              from              '              ./server-global              '              ;              const              instance              =              ServerGlobal              .              getInstance              ()                      

Enter fullscreen mode Exit fullscreen style

Now let's manage the MongoDB connection and the winston logger setup. So nosotros want to connect to MongoDB and setup the logger ONLY One time - because, why would we want to institute connexion or setup the logger twice?
For this, nosotros tin can apply the form constructor. As we saw, the constructor would only run one time considering we only create i instance of the form.

So first thing - permit's connect to MongoDB using the mongoose package.

                          import              mongoose              from              '              mongoose              '              ;              import              winston              from              '              winston              '              ;              form              ServerGlobal              {              individual              static              _instance              :              ServerGlobal              ;              private              constructor              ()              {              mongoose              .              connect              (              process              .              env              .              DB_ENDPOINT              ,              {              useNewUrlParser              :              true              ,              useUnifiedTopology              :              true              ,              useCreateIndex              :              true              ,              useFindAndModify              :              false              ,              });              }              static              getInstance              ()              {              if              (              this              .              _instance              )              {              render              this              .              _instance              ;              }              this              .              _instance              =              new              ServerGlobal              ();              return              this              .              _instance              ;              }              }              export              default              ServerGlobal              ;                      

Enter fullscreen mode Exit fullscreen mode

That's all. Just nosotros missing i thing. What if the connectedness is either successfully setup or failed? We want to log information technology.
For this we would use form belongings to concord the winston logger object, and so we could use the logger in other places in the appliction:

                          import              path              from              '              path              '              ;              import              mongoose              from              '              mongoose              '              ;              import              winston              from              '              winston              '              ;              class              ServerGlobal              {              individual              readonly              _logger              :              winston              .              Logger              ;              private              static              _instance              :              ServerGlobal              ;              individual              constructor              ()              {              this              .              _logger              =              winston              .              createLogger              ({              level              :              '              info              '              ,              format              :              winston              .              format              .              combine              (              winston              .              format              .              timestamp              (),              winston              .              format              .              json              (),              ),              transports              :              [              new              winston              .              transports              .              Panel              (),              new              winston              .              transports              .              File              ({              filename              :              path              .              join              (              __dirname              ,              '              ../logs.log              '              ),              level              :              '              info              '              ,              }),              ],              });              mongoose              .              connect              (              process              .              env              .              DB_ENDPOINT              ,              {              useNewUrlParser              :              truthful              ,              useUnifiedTopology              :              true              ,              useCreateIndex              :              true              ,              useFindAndModify              :              false              ,              }).              then              (()              =>              this              .              _logger              .              info              (              '              MongoDB connectedness established successfully              '              ))              .              take hold of              ((              due east              :              mongoose              .              Error              )              =>              this              .              _logger              .              error              (              `MongoDB connection failed with error:                            ${              e              }              `              ));              }              static              getInstance              ()              {              if              (              this              .              _instance              )              {              return              this              .              _instance              ;              }              this              .              _instance              =              new              ServerGlobal              ();              return              this              .              _instance              ;              }              public              get              logger              ()              {              return              this              .              _logger              ;              }              }              export              default              ServerGlobal              ;                      

Enter fullscreen mode Go out fullscreen mode

And then now information technology's all setup. The merely thing left is to create the singleton right when your server boots.
So assume you accept some server.ts file in which you lot boot the server, and y'all as well want to log the boot and port. Then, the file would wait something like this:

                          import              http              from              '              http              '              ;              import              app              from              '              ./app              '              ;              import              ServerGlobal              from              '              ./server-global              '              ;              const              port              =              procedure              .              env              .              PORT              ;              app              .              set              (              '              port              '              ,              port              );              const              server              =              http              .              createServer              (              app              );              // Init global set up              ServerGlobal              .              getInstance              ();              ServerGlobal              .              getInstance              ().              logger              .              info              (              `Server is running on port                            ${              process              .              env              .              PORT              }              `              );                      

Enter fullscreen mode Go out fullscreen mode

As yous can see, In the last 2 lines, we created the singleton, so logged the port on which the server listen (Annotation that the showtime line is actually redundant).

Finally, if you would like to log some actions besides in your RestAPI controller, you could exercise it by simply importing the ServerGlobal and using its logger.

I practise recommend to take a look at the NestJS framework that as well using this pattern pattern using its Providers.

How To Single Instance Service Node Js,

Source: https://dev.to/talr98/singleton-design-pattern-use-case-with-node-js-typescript-express-js-5ebb

Posted by: guoarron1960.blogspot.com

0 Response to "How To Single Instance Service Node Js"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel