Representational State Transfer is a software architectural style that defines a set of constraints to be used for creating Web services. Web services that conform to the REST architectural style, termed RESTful Web services, provide interoperability between computer systems on the Internet
What is REST
REST is acronym for REpresentational State Transfer. It is architectural style for distributed hypermedia systems and was first presented by Roy Fielding in 2000 in his famous dissertation.
Like any other architectural style, REST also does have it’s own 6 guiding constraints which must be satisfied if an interface needs to be referred as RESTful. These principles are listed below.
Guiding Principles of REST
- Client–server – By separating the user interface concerns from the data storage concerns, we improve the portability of the user interface across multiple platforms and improve scalability by simplifying the server components.
- Stateless – Each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.
- Cacheable – Cache constraints require that the data within a response to a request be implicitly or explicitly labeled as cacheable or non-cacheable. If a response is cacheable, then a client cache is given the right to reuse that response data for later, equivalent requests.
- Uniform interface – By applying the software engineering principle of generality to the component interface, the overall system architecture is simplified and the visibility of interactions is improved. In order to obtain a uniform interface, multiple architectural constraints are needed to guide the behavior of components. REST is defined by four interface constraints: identification of resources; manipulation of resources through representations; self-descriptive messages; and, hypermedia as the engine of application state.
- Layered system – The layered system style allows an architecture to be composed of hierarchical layers by constraining component behavior such that each component cannot “see” beyond the immediate layer with which they are interacting.
- Code on demand (optional) – REST allows client functionality to be extended by downloading and executing code in the form of applets or scripts. This simplifies clients by reducing the number of features required to be pre-implemented.
Resource – The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service, a collection of other resources, a non-virtual object (e.g. a person), and so on. REST uses a resource identifier to identify the particular resource involved in an interaction between components.
The state of resource at any particular timestamp is known as resource representation. A representation consists of data, metadata describing the data and hypermedia links which can help the clients in transition to next desired state.
The data format of a representation is known as a media type. The media type identifies a specification that defines how a representation is to be processed. A truly RESTful API looks like hypertext. Every addressable unit of information carries an address, either explicitly (e.g., link and id attributes) or implicitly (e.g., derived from the media type definition and representation structure).
Resource Methods – Other important thing associated with REST is resource methods to be used to perform the desired transition. A large number of people wrongly relate resource methods to HTTP GET/PUT/POST/DELETE methods.
Roy Fielding has never mentioned any recommendation around which method to be used in which condition. All he emphasizes is that it should be uniform interface. If you decide HTTP POST will be used for updating a resource – rather than most people recommend HTTP PUT – it’s alright and application interface will be RESTful.
Ideally, everything that is needed to change the resource state shall be part of API response for that resource – including methods and in what state they will leave the representation.
A REST Server simply provides access to resources and REST client accesses and modifies the resources using HTTP protocol. Here each resource is identified by URIs/ global IDs. REST uses various representation to represent a resource like text, JSON, XML but JSON is the most popular one.
HTTP Methods
Following four HTTP methods are commonly used in REST based architecture.
- GET − This is used to provide a read only access to a resource.
- PUT − This is used to create a new resource.
- DELETE − This is used to remove a resource.
- POST − This is used to update a existing resource or create a new resource.
RESTful Web Services
A web service is a collection of open protocols and standards used for exchanging data between applications or systems. Software applications written in various programming languages and running on various platforms can use web services to exchange data over computer networks like the Internet in a manner similar to inter-process communication on a single computer. This interoperability (e.g., communication between Java and Python, or Windows and Linux applications) is due to the use of open standards.
Web services based on REST Architecture are known as RESTful web services. These webservices uses HTTP methods to implement the concept of REST architecture. A RESTful web service usually defines a URI, Uniform Resource Identifier a service, which provides resource representation such as JSON and set of HTTP Methods.
Creating RESTful for A Library – Consider we have a JSON based database of users having the following users in a file users.json:
{
“user1” : {
“name” : “mahesh”,
“password” : “password1”,
“profession” : “teacher”,
“id”: 1
},
“user2” : {
“name” : “suresh”,
“password” : “password2”,
“profession” : “librarian”,
“id”: 2
},
“user3” : {
“name” : “ramesh”,
“password” : “password3”,
“profession” : “clerk”,
“id”: 3
}
}
Based on this information we are going to provide following RESTful APIs.
URI | HTTP Method | POST body | Result |
listUsers | GET | empty | Show list of all the users. |
addUser | POST | JSON String | Add details of new user. |
deleteUser | DELETE | JSON String | Delete an existing user. |
:id | GET | empty | Show details of a user. |
I’m keeping most of the part of all the examples in the form of hard coding assuming you already know how to pass values from front end using Ajax or simple form data and how to process them using express Request object.
Listing Data
Let’s implement our first RESTful API listUsers using the following code in a server.js file −
server.js
var express = require(‘express’);
var app = express();
var fs = require(“fs”);
app.get(‘/listUsers’, function (req, res) {
fs.readFile( __dirname + “/” + “users.json”, ‘utf8’, function (err, data) {
console.log( data );
res.end( data );
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log(“Example app listening at http://%s:%s”, host, port)
})
Now try to access defined API using URL: http://127.0.0.1:8081/listUsers and HTTP Method : GET on local machine using any REST client. This should produce following result −
You can change given IP address when you will put the solution in production environment.
{
“user1” : {
“name” : “mahesh”,
“password” : “password1”,
“profession” : “teacher”,
“id”: 1
},
“user2” : {
“name” : “suresh”,
“password” : “password2”,
“profession” : “librarian”,
“id”: 2
},
“user3” : {
“name” : “ramesh”,
“password” : “password3”,
“profession” : “clerk”,
“id”: 3
}
}
Adding Data
Following API will show you how to add new user in the list. Following is the detail of the new user
user = {
“user4” : {
“name” : “mohit”,
“password” : “password4”,
“profession” : “teacher”,
“id”: 4
}
}
You can accept the same input in the form of JSON using Ajax call but for teaching point of view, we are making it hard coded here. Following is the addUser API to a new user in the database −
server.js
var express = require(‘express’);
var app = express();
var fs = require(“fs”);
var user = {
“user4” : {
“name” : “mohit”,
“password” : “password4”,
“profession” : “teacher”,
“id”: 4
}
}
app.post(‘/addUser’, function (req, res) {
// First read existing users.
fs.readFile( __dirname + “/” + “users.json”, ‘utf8’, function (err, data) {
data = JSON.parse( data );
data[“user4”] = user[“user4”];
console.log( data );
res.end( JSON.stringify(data));
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log(“Example app listening at http://%s:%s”, host, port)
})
Now try to access defined API using URL: http://127.0.0.1:8081/addUser and HTTP Method : POST on local machine using any REST client. This should produce following result −
{
“user1”:{“name”:”mahesh”,”password”:”password1″,”profession”:”teacher”,”id”:1},
“user2”:{“name”:”suresh”,”password”:”password2″,”profession”:”librarian”,”id”:2},
“user3”:{“name”:”ramesh”,”password”:”password3″,”profession”:”clerk”,”id”:3},
“user4”:{“name”:”mohit”,”password”:”password4″,”profession”:”teacher”,”id”:4}
}
Showing Detail
Now we will implement an API which will be called using user ID and it will display the detail of the corresponding user.
server.js
var express = require(‘express’);
var app = express();
var fs = require(“fs”);
app.get(‘/:id’, function (req, res) {
// First read existing users.
fs.readFile( __dirname + “/” + “users.json”, ‘utf8’, function (err, data) {
var users = JSON.parse( data );
var user = users[“user” + req.params.id]
console.log( user );
res.end( JSON.stringify(user));
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log(“Example app listening at http://%s:%s”, host, port)
})
Now try to access defined API using URL: http://127.0.0.1:8081/2 and HTTP Method : GET on local machine using any REST client. This should produce following result −
{“name”:”suresh”,”password”:”password2″,”profession”:”librarian”,”id”:2}
Deleting Data
This API is very similar to addUser API where we receive input data through req.body and then based on user ID we delete that user from the database. To keep our program simple we assume we are going to delete user with ID 2.
server.js
var express = require(‘express’);
var app = express();
var fs = require(“fs”);
var id = 2;
app.delete(‘/deleteUser’, function (req, res) {
// First read existing users.
fs.readFile( __dirname + “/” + “users.json”, ‘utf8’, function (err, data) {
data = JSON.parse( data );
delete data[“user” + 2];
console.log( data );
res.end( JSON.stringify(data));
});
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log(“Example app listening at http://%s:%s”, host, port)
})
Now try to access defined API using URL: http://127.0.0.1:8081/deleteUser and HTTP Method : DELETE on local machine using any REST client. This should produce following result −
{“user1”:{“name”:”mahesh”,”password”:”password1″,”profession”:”teacher”,”id”:1},
“user3”:{“name”:”ramesh”,”password”:”password3″,”profession”:”clerk”,”id”:3}}