Ad

NodeJS Performance - Multiple Routes Vs Single Routes

- 1 answer

I have created a single endpoint in Node.js.

Following is the end-point:

app.post('/processMyRequests',function(req,res){

switch(req.body.functionality) {
    case "functionalityName1":
        jsFileName1.functionA(req,res);
        break;
    case "functionalityName2":
        jsFileName2.functionB(req,res);
        break;
    default:
        res.send("Sorry for that");
        break;
}
});

In each of these functions, calls to APIs are done, then the data is processed, and finally response is sent back.

My questions:

  1. Since Node.js as a default handles requests asynchronously, can we have a single route for all the responses?
  2. Will concurrency be an issue i.e. when parallel hits are happening into the single route will Node.js stall or slow down?
  3. If the answer to question (2) is YES, how will it change when I have separate routes i.e if the same amount of requests come into a specific route then it is going to be the same issue right?

Would be happy if someone could share real-time use cases. Thanks

Ad

Answer

  1. You technically can have a single route for all the responses, but it's considered "better-practice" to create endpoints which are compact, clear in what the intended function/purpose is, and not too complex; in your example, there could be many possible branches of code that the route could take. This requires unique logic for each branch, which adds to the complexity of your endpoints, and takes away from the clarity of the code. Imagine that when an error occurs, you now have to debug potentially multiple different files and different branches of your endpoint, when you could have created a separate endpoint for each unique "branch".
    • As your application grows in both size, and complexity, you are going to want an easy way to manage your API. Putting lots of stuff into one endpoint is going to be a nightmare for you to maintain, and debug.
    • It may be useful for you to look at some tutorials/docs about how to design and implement an API, here is a good article from Scotch.io

Example for question one:

// GET multiple records
app.get('/functionality1',function(req,res){
   //Unique logic for functionality
});

// GET a record by an 'id' field
app.get('/functionality1/:id',function(req,res){
   //Unique logic for functionality
});

// POST a new record
app.post('/functionality1',function(req,res){
   //Unique logic for functionality
});

// PUT (update) a record
app.put('/functionality1',function(req,res){
   //Unique logic for functionality
});

// DELETE a record
app.delete('/functionality1',function(req,res){
   //Unique logic for functionality
});

app.get('/functionality2',function(req,res){
  //Unique logic for functionality
});
...

This gives you a much clearer idea of what is happening for each endpoint, versus having to digest a lot of technically unrelated logic in a single API endpoint. Summing it up, it's better to have endpoints which are clear and concise in their purpose, and scope.

  1. It really depends on how the logic is implemented; obviously Node.js is single-threaded. This means it can only process 1 "stream" of code at a time (no true concurrency or parallelism). However, Node gets around this through its event-loop. The problem that you could see depends on if you wrote asynchronous (non-blocking) code, or synchronous (blocking) code. In Node it's almost always better and recommended to write non-blocking code. This helps to prevent blocking the event loop, meaning your node app can do other things while, for example waiting for a file to finish being read, an API call to finish, or a promise to resolve. Writing blocking code will result in your application bottle-necking/"hanging", which is perceived by your end-users as higher-latency

  2. Having multiple routes, or a single route isn't going to resolve this problem. It's more about how you are utilizing (or not utilizing) the event loop. It's extremely important to use asynchronous code as much as possible.

    • One thing that you can do if you absolutely must use synchronous code (this is actually a good approach to leverage regardless of code synchronicity)is to implement a microservice architecture, where a service can process your blocking (or resource-intensive) code off of your API Node service. This frees up your API service to handle requests as rapidly as possible, and leave the heavy lifting to other services.
    • Another possibility is to leverage clustering. This gives you the ability to run node as if it were multi-threaded, by spawning "worker" processes, which are identical to your master process, with the difference in that they are able to process work individually. This type of approach is extremely useful if you expect that you will have a very busy API service.

Some extremely helpful resources:

Ad
source: stackoverflow.com
Ad