This article is part of a series with the name IoT Remote Power Switch – Project Part 6.
It describes the implementation of a native REST API in Node.js and how it can be tested.
REST API – What is it?
What is a REST API and why is it important to this project?
REST stands for Representational State Transfer and defines a programming paradigm for distributed systems, especially for web services. REST is an abstraction of the structure and the behavior of such services. REST requires that an URI (address) represents the contents of exactly one web page (or – more generally speaking – one resource). It requires furthermore that a RESTful web server responds with the same content on multiple requests for the same URI.
REST was initially proposed by Roy Thomas Fielding in his year 2000 PhD dissertation “Architectural Styles and the Design of Network-based Software Architectures”. Fielding developed the REST architectural style in parallel with HTTP 1.1 of 1996-1999, based on the existing design of HTTP 1.0 of 1996.
(Some parts of this text were copied and pasted from Wikipedia.)
Let’s assume there exists a RESTful web service at the address
http://www.blueservers.com. The purpose of this service would be storing and returning the states of many Remote Power Switches located all over the world. The API of this service could then look like this:
http://www.blueservers.com/status. status is called an end point or route. Under this end point the status of Remote Power Switches could be queried (by browsers) or set (by the Remote Power Switches) by extending the end point with their identifier. Example:
http://www.blueservers.com/status/13792881. A browser would query this URI with a GET message (more on this see below). The response from the server would be a message with the payload ‘off’, ‘on’ or ‘offline’.
The Remote Power Switches would update their status by using the same end point, but by submitting a POST message with the status attached to the end point like the following:
http://www.blueservers.com/status/13792881/on. The status could be ‘off’ or ‘on’.
REST and HTTP
REST APIs aren’t reserved to the HTTP (or HTTPS) protocols, but it’s a common protocol for this kind of transactions. HTTP supports the messages POST, GET, PUT and DELETE (and others), which map nicely to the database operations Create, Read, Update and Delete. (The first letters of these four verbs form the abbreviation CRUD, which is a technical term among database developers.)
The HTTP messages are used in combination with the end points to define the action (HTTP message like GET) and the target (end point like status). A GET operation on the status target in combination with a device identifier would therefore return the status of a Remote Power Switch, while a POST operation in combination with a device identifier would create a new status entry of a switch in the server’s database.
REST, JSON and HTML
Machine to machine communication usually uses XML or JSON format. JSON formatted messages are smaller in size compared to XML messages, and they are easier to read by programmers. There exist light weight libraries in almost any programming language for encoding and decoding JSON messages. Since the exchanged data’s structure is very simple in my case, JSON is my choice.
So, my embedded computer that controls the power switch sends and receives JSON formatted messages to and from the web server.
The web browser on the other hand requires HTML messages for the page build. Such messages are sent by that part of the web server that is responsible for serving the static pages. The dynamic parts of the page like the field that displays the status of the Remote Power Switch can be updated using JSON formatted messages. Luckily, the jQuery library supports JSON based message exchange with the server, thus no HTML or XML messages are required. This simplifies server programming because the server’s REST API has only to support JSON messages.
The database should already be running. I’ve shown how to install it here. After the installation it is running. But it’s still empty. The way I have programmed the Node.js server application, HTTP requests with unknown device identifiers return an error message. Thus, I have to add at least two entries per Remote Power Switch I want to support: one in the status collection and one in the switches collection.
This can be done by importing a JSON formatted data file from the Linux command line to the database. The two required commands look as follows:
$> cd <to/project/top/level/directory> $> mongoimport --db rps --collection status --file data/status.json $> mongoimport --db rps --collection switches --file data/switches.json
The database will echo the outcome of the import on the command line. The two files are part of the git repository, thus the commands should work straight away.
Testing the Interface with Postman
After starting the web server with the command
$> cd <to/project/top/level/directory> $> node server/app
it is ready to be tested. However, a web browser isn’t of much help here since it sends GET messages to the server and requests text/HTML messages, while we require JSON formatted messages. In addition we also want to send POST messages.
Google has developed an extension for Chrome that is called Postman. This tool allows us to send many different kinds of messages to a web server.
You can use any other convenient tool of your choice of course.
With Postman I have the tool to test the interface. In order to test it I also need the detailed API including the routes, the data they take and the supported HTTP messages. This information is encoded in the source code of the web server, since it’s the code that defines the API.
It’s a bit inconvenient for me to read the source code every time I want to test the web interface, thus I’ve appended some test command examples to the release notes of v0.4 (link is provided below). They cover all available routes and HTTP messages.
Summary and Outlook
You can find the source code here; it’s pre-release v0.4. Note that the
node_modules folder isn’t part of the repository. After downloading the repo or its zip file you’ll have to change directory to the top-level folder of the project and run
$> npm install.
You may have noticed that compared to the previous release I’ve renamed the file switchOffOn.js to switches.js. In addition, I’ve refactored the model.js file and implemented the end point functions get() and set() in the files status.js or switches.js respectively. Finally, I’ve updated the file server.js to account for the added functionality.
After adding initial data to the database and starting the application on the command line, its functionality can be tested by using Chrome’s Postman extension.