Build a microservices architecture with Node.Js for Beginners

Building JavaScript applications on microservices help you focus on developing monofunctional modules with clearly defined operations and precise interfaces. The application development process becomes more agile, and the challenges of continuous testing are mitigated.

When you build applications on a monolithic architecture, the entire application needs to be deployed with every update. On the other hand, microservices have no dependency on the type of framework, technique or programming language being used to build them. Your ability to release REST-ful APIs for communication and other services is the only requisite for microservice architecture.

To run the application smoothly, it is essential to convert the large, homogeneous structure into small, independent pieces of programs. Such complexities can be resolved effortlessly when JavaScript applications are built on microservices, more so with the Node.js ecosystem.

Building Microservices with Node.js

To build microservices for real-world applications with Node.js, a basic understanding of JavaScript programming is important. The steps involved in developing microservices with Node.js showcase how working applications in our hyperconnected world can perform superbly when constructed with a functional combination of multiple, unique APIs.

To understand the process better, let’s use Node.js to build a microservice for connecting external APIs. As the development progresses, improvements will be made to make the microservice more responsive and cost-effective.

1. Assess the Business Need

To build this microservice, let’s assume that a business requires a service that identifies two ZIP codes and provides the distance between them. The distance is calculated in miles. You’ll need to use validation techniques for ZIP code identification and distance calculation. The requirement wants the service to configure external API calls. And, it is essential to quickly duplicate calls and make the process more cost-efficient. For this, an internal cache can be implemented.

2. Initialization

To begin with, install Node.js on your computer or workstation. Installing the Node.js

8.1.1 version is recommended. To download the latest version of Node.js, visit Nodejs.org.

NPM (Node.js packet manager) is included in the installation suite. There are several stages where you need to use the NPM. For building this microservice, NPM will be used for launching the project, loading the dependencies, and executing the service.

To initialize the project,

  1. Open Node.js platform
  2. Go to the root folder
  3. Run the command: **$ npm init **

Executing the command initiates the walk-through for _package.json _file creation. By creating the package.json, the project establishes its foundation. The name and version of the service are entered, or you can choose from the defaults and update later.

The microservice will be built on two primary packages - _Request _and Express.

The _Request _package enables the microservice to set up a connection with third-party, web-based APIs. The _Express _package is a structure for Node applications used for supporting the Node.js foundation of the microservice.

To add these packages to the _package.json _file,

  1. Enter the command: $ npm install express request
  2. At the end of the command, add: **–save **
  3. Run the command

The **npm init **command has developed a structure of files and folders for creating the microservice. The primary file is called server.js. API support files are stored in the api folder. Third-party API connection logic is saved in the _service _folder. Other key folders include node_modulespackage-lock.json, and package.json.

node_modules folder [https://blog.cloud66.com/caption]

The _Express _and _Request _packages are saved to this structure as dependencies in the _node_modules _folder.

Now, the coding for microservice can begin.

3. Setting up the Server

The first part of the coding involves building a server that recognizes and accepts the requests. For this, you need to begin with the server.js file, which is the primary file of the project. The code used to create _server.js _file goes like this:

var express = require('express')
var app = express();
var port = process.env.PORT || 3000;

var routes = require('./api/routes');
routes(app);
app.listen(port,function(){
console.log('Server started on port: ' + port);
});

The next step would be specifying the routes for response transmission. The server created earlier assigns routes that ensure all requests are processed.

4. Specifying the Routes

Defining the routes is a critical stage in microservice development. The routes are defined by two end-points for dispatching and accepting requests.

In this project, the _Express _package is added to the _sever.js _file and is further used to build a new app object. In JavaScript development, an app object is responsible to set or remove attributes from the application scope. Now, the port is specified, and the system properties are configured according to the process object. The role of the process object is to execute the process by performing the input, running the specified process, checking the output status of the process, and ending the process thereafter.

The default port specification is valued at 3000. By specifying _PORT _as the environment variable, you can choose to define the port number (value) based on the system running this application.

In the next stage, a route object is transmitted to the API folder from the _routes.js _file. While doing so, the app object (created earlier) is carried forward with the routes object. This allows the app to start wiretapping the port that was defined. As this process gets completed, the app displays a message to the console.

Each route defined to the server needs to assigned to a controller object target. To build the controller object, use the two end-points and an about endpoint that provides the application information. For this project, both the ZIP codes will be used as the two parameters defining the path for distance endpoints. When the target is assigned, the endpoint displays the distance between the two ZIP codes, calculated in miles.

'use strict';

var properties = required('../package.json')
var distance = require('../service/distance');

var controllers = {
about: function(req,res){
var aboutInfo = {
name:properties.name,
version: properties.version
}
res.json(aboutInfo);
},
get_distance:function(req, res){
distance.find(req, res, function(err,dist){
if(err)
res.send(err);
res.json(dist);
});
},
};

New JavaScript versions enforce the security for coding practices by employing the use strictdirective. To state the functions inside a module, **module.exports **is used. This way, the stated functions are can be used by keeping them available in another file which includes the routes module. The routes module specifies the routes for the Express package and is imported from the _server.js _folder.

At this stage of the process, two routes are added to the microservice. The GET requests are transmitted with the first route on the **/about **endpoint. The function of the controller responds to these requests. The second route processes the GET requests on **/distance **endpoint, and the controller use the get_distance function to handle them. The two parameters, “zipcode1” and “zipcode2”, are specified respectively.

The controller object that handles these requests is created in the next stage. It is important to exclude the controller object from the _server.js _file or the routes.js file functions so that all files can access it.

5. Building the Controller

Adding controller logic to the microservice equips it with some interesting functions. A controller object interprets user intentions and actions and communicates the new or modified data to process objects.

For this microservice, a controller object with two properties needs to be created in the controller file. The two properties are nothing but the functions of handling the requests received from the routes module.

'use strict';
var properties = required('../package.json')
var distance = require('../service/distance');
var controllers = {
about: function(req,res){
var aboutInfo = {
name:properties.name,
version: properties.version
}
res.json(aboutInfo);
},
get_distance:function(req, res){
distance.find(req, res, function(err,dist){
if(err)
res.send(err);
res.json(dist);
});
},
};

module.exports = controllers;

By using this code, the _properties _controller object is created. It references the _package.json _file created at the first step of this project. With this object, the process object can import and use the informational contents of the _package.json _file.

The code also has two distinct parts - the about function and the get_distance function. The first functionality accepts response objects and requests. For executing the _about _functionality, a new object from the _package.json _file is returned as a response object.

The _get_distance _functionality syncs the distance module with the find function (also called the callback function). It accepts the distance objects as well as the error objects. In case of errors, the find function sends back the response object.

6. Establishing the External API Call

Now that the controllers are added, an external service is ready to be executed. This is the final part of the microservice development with Node.js. Here, the third-party API call is handled by the API file. To get the API key, you can get is free from ZIPCODEAPI.com. To make the external call, set an expired test key as the default key.

var request = require('request');

const apiKey = process.env.ZIPCODE_API_KEY ||
"(Your API key)"
const zipCodeURL = 'https:,'/mwa.zipcodeapi . com/rest/';

var distance = {
find: function(reg, res, next) {
request (zipCodeURL + apikey
+'/distance.json/' + req.params.zipcode1 + '/'
+ req.params.zipcode2 + '/mile',
function (error, response, body) {
if ( !error && response. statusCode = 200) {
response = JSON.parse(body);
res.send(response);
} else {
console.log(response.statusCode + response.body);
res.send({distance: -1});
}
});

}
};

module.exports = distance;

The code runs the Request package to make the external HTTP request, which needs to be updated for testing error conditions. The code enables the find function to accept the parameters for objects namely - requestresponse, and next. URL of the service is accepted by the request object. Callback function handles the response object.

“HTTP Status code 200” is the status of the response object, provided there are no errors. The body of the response is parsed out and returned. Instead of forwarding directly, parsing the response allows the response to be handled with maximum efficiency.

7. Execution

Eventually, the distance object is exported, and the controller can represent the concrete instances and functions of the external API calls as needed. To wrap up the execution of this microservice, the code needs to be reviewed for typos in the command.

Challenges of Building Microservices in Node.js

Before creating microservices with Node.js, you should also be aware of certain challenges that come with the programming platform. Some of the critical drawbacks of building JavaScript microservices with Node.js include:

  • Unable to process CPU bound tasks: Node.js is single-threaded and cannot compute CPU-heavy tasks. The application experiences performance bottlenecks as the whole CPU bandwidth gets used for processing heavy requests. An experimental feature in Node.js 10.5.0 update has introduced multithreading to fix this challenge.
  • Poor NPM tools: Besides the core NPM tools, a majority of tools on the Node.js platform are not properly tested or documented. The registries are unorganized, and the open-source ecosystem is not adequately supervised by Joyent, the creators of Node.js.
  • Callback hell: The callback function is heavily used to run each task. When the tasks exceed a limit, the situation leads to a “callback hell” and maintaining the code becomes near-impossible. The code can, however, be simplified and re-factored to lower the impact of the asynchronous nature of Node.js on callback functions.
  • Lack of Node.js developers: There aren’t as many Node.js developers when compared to the presence of JavaScript developers. The growing demand for Node.js remains unsatisfied due to the lack of professional experience of developers on this relatively new programming technology.

Despite these drawbacks, Node.js is still observed as a suitable environment to build real-world applications and JavaScript microservices. The basic distributed system of microservice architecture with Node.js shows you how to separate applications build communications between services. The RESTful APIs process the data and maintain the code towards the deployment of each microservice. In the years to come, Node.js will be actively used in building mature, open-source tools and developing microservices for enterprise-level software.

#javascript #node #node_js

Build a microservices architecture with Node.Js for Beginners
18.70 GEEK