Relying on JSON to Format Data
Microservices rely on JavaScript Object Notation (JSON) for transferring both requests and responses. Yes, you can also send data using REST, but the information ultimately ends up in JSON format. There are three main reasons that you want to use JSON to transfer data:
- Clean Data: The data format for JSON is straightforward. The data appears in two forms: name/value pairs or as a list of values. Because the data format is so strict and simple, there is less chance for error when transferring data and therefore, fewer reliability and security issues.
- Efficiency: Because JSON avoids the whole tagged appearance of both HTML and XML, it tends to be smaller than other sorts of data transfers. The information is still in text form, but the format itself is quite efficient, which means you waste fewer resources transferring the data.
- Scalability: The strict data format used by JSON means that data transfers are standardized, which makes it easier to expand your application as needed. Using a single data structure means that you can plug in your code anywhere that you need it.
If you haven’t worked with JSON before, it’s helpful to get a tutorial on using it. JSON is straightforward, but the example will make more sense if you know how JSON works. The W3Schools hosts one of the best JSON tutorials available. You can also find a nifty tutorial on the TutorialsPoint site.
Getting Microservices to Talk with REST or SOAP
Microservices rely on Represetational State Transfer (REST), which is an architectural style of communication, because it’s lighter weight than protocols such as the Simple Object Access Protocol (SOAP). Using SOAP does have advantages in some situations, but it presents problems in Internet scenarios- for more info you can read "Understanding REST Vs SOAP" and "SOAP vs REST Challenges". For example, SOAP requires significant use of bandwidth and it needs a more formal level of communication between client and server. Applications that rely on REST for communication are called RESTful applications. Using REST for microservices provides the following advantages:
- Decouples consumers from producers
- Provides stateless communication
- Allows use of a cache
- Allows use of a layered system
- Provides a uniform interface
You have a number of options for using REST with microservices. However, the easiest method (and the method used for the example) is to rely on a specially formatted URL. For example, http://localhost:10101/act?say=hello is the URL used for the example. In this case, you contact the localhost using a special port, 10101. You send a message using act. The message is interpreted as a JSON name/value pair, {say:"hello"}. The example demonstrates how this all works, but the idea is that you send a request and then get back a JSON response. Using REST for communication makes things simple.
Creating the Microservice Using Node.js and Seneca
You could create a microservice completely from scratch, but like everything else today, things go a lot easier if you can get someone else to do the heavy lifting for you. In this case, the example begins with Node.js—a platform built on Chrome's JavaScript runtime. You use it to create fast, scalable network applications. Seneca is a toolbox built on top of Node.js that makes it easy to create microservices.
You can find a number of examples for using Node.js and Seneca to create a microservice online. Unfortunately, most of them are convoluted and difficult to use. Some are simply outdated. The example provided in this article works with the 0.12.4 version of Node.js and the 0.6.2 version of Seneca.
The example assumes that you have installed Seneca as a subdirectory in the example directory. What you should see in the example directory is a folder structure that contains node_modules\seneca. To begin this example, you create the microservice shown here and place it in a file named service.js:
require('seneca')()
.add(
{ say:"hello"},
function( message, done )
{
done( null, {message:'hello'} )
})
.listen()
In this example, require('seneca') loads the Seneca library into memory. The code then adds a match pattern of { say:"hello"} as a JSON object. The function() associated with the match pattern outputs another JSON object, {message:'hello'}. The example purposely uses both single and double quotes when creating JSON objects to show that it is possible, even if the official specifications don’t seem to say so. The final step is to tell the service to listen(). You can add a port number to the listen() function. If you don’t provide a port number, the service listens at the default port of 10101. To start the service, you type node server.js and press Enter at the command prompt. You see startup messages like the ones shown in Figure 1.
The startup process logs two steps. The first is the initialization process for Seneca (where Seneca says hello on the third line of the output in Figure 1). The second is placing the microservice in listen mode (as shown on the fifth line). Whenever the microservice makes a call or performs some other task (other than simple output), you see one or more log entries added to the window.
Of course, you’ll want to test the microservice. Open your browser window and type http://localhost:10101/act?say=hello as an address. The microservice outputs a simple JSON object as shown in Figure 2.
When you look back at the console window, you don’t see anything. That’s because the function output a simple JSON object and didn’t make any calls outside the environment. However, try typing http://localhost:10101/act?say=goodbye as a request. Now you see some activity in the console window as shown in Figure 3.
The output includes a stack trace, which you can ignore in this case, but could prove helpful when working with complex microservices. The most important information appears at the top in this case. You see a warning that there is no matching pattern for { say: 'goodbye' }. Notice that the REST request is translated into a JSON object. The error output tells you precisely what happened, so it’s harder for someone to get by with an invalid request.
When you finish working with the example, press Ctrl+C or Ctrl+Break to stop the service. The service will stop and you’ll see the command prompt reappear.
The Bottom Line
Creating a microservice doesn’t have to be hard. You don’t need any special equipment and you can experiment with them as much as you like on your own system. Remember that microservices are small and tend to focus on performing a single task well.
Further Resources