12/23/2019 Beginners Guide to Building Real-World Microservices with Node.
js
Products Blog Try it free
← All Articles
Beginners Guide to
Building Real-World
Microservices with Node.js
Mike Mackrory 12 SEPTEMBER 2018
This is a guest post by Mike Mackrory, a Senior Engineer
on a Quality Engineering team and a technical writer at
Sweetcode.
This article is intended to be a quick-start guide for
developing real-world microservices with Node.js. It’s the
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 1/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
article that I would have liked to read when I started
Products Blog Try it free
programming with Node.js. Therefore, you won’t find the
words “Hello” or “World” anywhere in this article (at least,
not more than that first mention). You should have a basic
understanding of Javascript, but other than that, follow the
steps for a working application.
In our highly connected world, projects can be constructed
by combining functionality from different APIs in unique
and performant ways. In this example, we’re going to
create a microservice using Node.js which connects to an
external API, and then look at improvements we can make
to make it more cost-effective and performant.
The business requirement for this service is to accept two
Zip Codes and return the distance between them in miles.
We’ll look at validation techniques, the configuration for an
external API call, and implement an internal cache to make
duplicate calls faster and more cost-efficient.
Initial Steps
You’ll need to have Node.js installed on your workstation
for this example. I’m using version 8.11, and you can
download the latest version for your operating system from
Nodejs.org. The Node.js installation includes NPM, which
is the Node.js package manager. We’ll use NPM to
bootstrap the project, install dependencies and execute
the service. (You can follow along with this example or
view the completed example in this GitHub repository.)
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 2/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
We’ll start by initializing the project using npm init. Run this
Products Blog Try it free
command in the root folder for the project. The command
walks you through the creation of the package.json file,
which is the foundation for the project. If you’re not sure of
an answer, accept the default, and we can update it later if
necessary. We’ll be using the name and version a little
later.
$ npm init
We’re going to use a package called Express to build our
service. Express is an established framework for Node
applications and continues to benefit from the support of
the Node.js Foundation. We’re also going to use the
Request package to enable us to connect with a third-
party API on the Web.
We’ll add these packages to our project with the following
command (the save flag at the end of the command adds
it to the package.json file which was created by NPM).
$ npm install express request --save
One last thing before we delve into the code. Let’s look at
the structure of how it’s all going to fit together. There are
two files and a folder created by the npm init command.
These are package.json, package-lock.json, and
node_modules. When we installed the express and
request packages, their dependencies were downloaded
and saved in node_modules.
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 3/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
Products Blog Try it free
The primary file in our project is named server.js. We’ll
have files to support the API in a folder called api, and
we’ll add the logic to connect to a third-party API in the
service folder.
Let’s build our service!
Creating a Server to Accept Requests
We’ll start from our primary file, then define the routes, add
controllers, and finally, build the connection to an external
service.
Create a file in the root folder for your project called
server.js. This file contains the code below. I’ll step through
each part of it, so you can see how it goes together.
var express = require('express')
var app = express();
var port = process.env.PORT || 3000;
var routes = require('./api/routes');
routes(app);
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 4/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
app.listen(port, function() {
Products Blog Try it free
console.log('Server started on port: ' + port);
});
This file creates our server and assigns routes to process
all requests. We’re going to have two endpoints which we’ll
define in the next step.
The first thing we’ll do is to bring the express package into
the file. We’ll use this to create a new app object. We’ll
also specify the port. The process object is used to
reference system properties. If I want to define the port
number based on the machine running the application, I
can define an environment variable called PORT, and it
will be used. The default port value is 3000 if it isn’t
defined.
The next line brings in a routes object from the routes.js
file in the api folder. We’ll pass the app to this object, and
that sets the routes for our application. Finally, we’ll tell the
app to start listening on the port we defined, and to display
a message to the console when this process is complete.
Defining the Routes
The next step is to define the routes for the server and
assign each to a target in our controller object. We’ll build
the controller in the next step. We’ll have two endpoints.
An about endpoint returns information about the
application. A distance endpoint includes two path
parameters, both Zip Codes. This endpoint returns the
distance, in miles, between these two Zip Codes.
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 5/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
'use strict';
Products Blog Try it free
var controller = require('./controller');
module.exports = function(app) {
app.route('/about')
.get(controller.about);
app.route('/distance/:zipcode1/:zipcode2')
.get(controller.get_distance);
};
The ‘use strict’ directive at the top of the file is used by
new versions of Javascript to enforce secure coding
practices. (You can learn more about that here.) The first
thing we’ll do is to create a controller object which we’ll
define in the next step. Because we declare this outside of
any functions in the file, it is accessible by all of them.
Module.exports allows us to declare functions inside a
module, and have them available for use in another file.
This file constitutes the routes module, which we imported
into our primary server.js file and used it to define the
routes for our express app.
This function adds two routes to the app. The first route
listens for GET requests on the /about endpoint. These
requests are handled by the about function in the
controller. The second route listens for GET requests on
the /distance endpoint. The get_distance function in the
controller handles these requests. Two parameters are
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 6/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
also specified. These are labeled zipcode1 and zipcode2
Products Blog Try it free
respectively.
Let’s build the controller to handle those requests.
Adding Controller Logic
One of the aspects of Javascript and Node.js which I find
interesting is that functions are objects. Within the
controller file, we’re going to create a controller object with
two properties. Those properties are the functions to
handle the requests we defined in the routes module.
'use strict';
var properties = require('../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);
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 7/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
});
Products Blog Try it free
},
};
module.exports = controllers;
We have two distinct parts to our controller. We’ll go
through the code for the about functionality first. At the top,
we create an object called properties which references the
package.json file which NPM created when it bootstrapped
the project. This file is in JavaScript Object Notation or
JSON for short. This format affords us the ability to import
and use the information it contains.
Within the controllers object, we define a property called
about. This property is a function which accepts request
and response objects. We’ll only use the response object
for this function. Using the name and version information
from the package.json file, we’ll build a new object and
return it as the response.
For the get_distance functionality, we’ll start by bringing in
the distance module. We’ll pass the request and response
objects to the find function within this module. This function
also includes a callback function. This function accepts an
error object (err) and a distance object (dist). If there is an
error in the response, we return that with our response;
otherwise, we send back the results of the find function.
Making the External Call
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 8/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
We’re ready for the final piece of the puzzle. This file
Products Blog Try it free
handles the call to a third-party API. We’ll use the distance
API provided by ZipCodeAPI.com. (You need an API key
to use this, and it is free if you register. You can also use
the key from the example if you want to test your service,
but this key frequently expires during the day.)
I set my key as an environment variable on my system and
named it ZIPCODE_API_KEY. The default key in the code
is an expired test key from the ZipCodeAPI website.
var request = require('request');
const apiKey = process.env.ZIPCODE_API_KEY ||
"hkCt1nW1wF1rppaEmoor7T9G4ta7R5wFSu8l1dokNz8y53gGZHDneWWVosbEYi
rC";
const zipCodeURL = 'https://www.zipcodeapi.com/rest/';
var distance = {
find: function(req, 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});
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 9/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
}
Products Blog Try it free
});
};
module.exports = distance;
We’re using the request package to execute the external
HTTP request, and we already discussed the api Key
above. Ensure that you update it unless you want to start
by testing the error conditions.
The find function accepts request, response and next
objects as parameters. The request object accepts the
URL of the service we’re calling and then defines a
callback function to handle the response.
If there are no errors, and the status of the response is
HTTP Status code 200, then the function parses out the
body of the response into an object called response and
returns it on the resp object. Since the ZipCodeAPI returns
with a JSON response, we could forward this directly.
Parsing it out allows us the option of doing more with the
response if we choose to.
We log failures to the console, and then a result of -1 is
sent on the response object. You may opt to create an
error object to return as well.
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 10/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
Finally, we export the distance object, which allows the
Products Blog Try it free
controller to instantiate it and call its functions as needed.
Execution and Debugging
Assuming there aren’t any typos, your application should
be ready to execute. Open a console window and run the
following commands—The first ensures that all the
packages used by the application are downloaded and up-
to-date:
$ npm install
The second command starts your application.
$ npm start
Assuming it starts correctly, and the port you define is
3000, you can now open your browser and navigate to:
http://localhost:3000/about
http://localhost:3000/distance/84010/97229
The following URL allows you to see the error condition
because 92001 is not a recognized Zip Code.
http://localhost:3000/distance/84010/92001
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 11/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
If you run into problems, I’ve found the error messages to
Products Blog Try it free
generally be helpful in pointing me to the line of code with
the offending syntax, missing punctuation, or other
problems. The Internet is also a wealth of information for
specific problems.
Related Content:
Kubernetes: Orchestrate your Node.js
(micro)services
DEMO: Use Maestro Clusters to speed up app
deployment on Kubernetes
Having fun with machine learning, Node and
Cloud 66
Deploying Your First Node App with Cloud 66
Sign up and start deploying Node.js services in a
production backed by Kubernetes. Use $50 Free
Credit Code: Node.js19
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 12/13
12/23/2019 Beginners Guide to Building Real-World Microservices with Node.js
← All Articles
Products Blog Try it free
Containers
Company
Jobs
Security
Contact
Products
Rails
Node
Maestro
Skycap
Open Source
Status
Status
Uptime
Connect
Twitter
GitHub
Connect
Documentation
Community Forum
Slack Channel
RealScale
2011-2019 © Cloud 66 Ltd. Privacy Legal
https://blog.cloud66.com/beginners-guide-to-building-real-world-microservices-with-node-js/ 13/13