Representational State Transfer (REST)
Representational State Transfer (REST) has become a popular method for organizing applications based on the HTTP protocol. It leverages HTTP message headers and protocol properties in a natural and highly interconnected way. In this section, we will outline the main features of RESTful (as it is commonly known) web service implementations.
REST web services are considered to have four main aspects:
- Use HTTP, and the message type (GET, POST, PUT, etc.) has a clear meaning;
- Communication is stateless;
- The directory structure of the data is visible to both the client and the server;
- Data is transmitted in XML or other MIME types specified in HTTP headers.
REST is considered an architecture or style for web service implementation.
REST was designed in parallel with the HTTP/1.1 protocol, so the two are closely related. In fact, the World Wide Web can be considered the largest application that conforms to RESTful architecture. The key connection lies in the strict interpretation of HTTP message types. For example, in RESTful systems, HTTP message types are used strictly as follows:
HTTP message type | use |
POST | Create resources on the server |
GET | Retrieve resources from server |
PUT | Update resources on the server |
DELETE | Delete resources on the server |
You may have noticed that when we first looked at HTTP message types, we did not impose these restrictions. In practice, POST and GET message types are often used interchangeably in many client/server systems. A RESTful system does not have this flexibility because it uses an explicit message type (as part of the protocol header) to express the requested functionality. Additionally, standard HTTP response messages indicating success or error status are designed for correct use of message types. For example, the following message might be returned by HTTP on a POST request, assuming correct usage:
201 (created)
The second property of RESTful systems is that they are stateless. Statelessness is a property that affects the efficiency of servers serving requests. It is more efficient because the request message must contain all the information required to perform the requested operation. The server has no state, so there is no need to store or retrieve information from previous requests or maintain a record of previous requests from the same client. However, it requires the client to retain enough information to construct the request. In other words, the server application no longer needs to track successive client requests, but leaves this task to the client.
To facilitate stateless interactions, RESTful systems utilize header definitions in HTTP messages. A useful header attribute is the cache control and last modified name-value pair. The server can use this information to inform the client if and when data needs to be reloaded from the server. Clients can use this information to determine whether additional network traffic is required to reload the latest data.
The third attribute of a RESTful system is a hierarchical resource structure (similar to a directory structure). This can easily be represented by the URI you use in web browsing. For example, a URI might look like this:
In a RESTful system, the URI should be static so that you can bookmark it and return the same resource later. There can also be multiple URIs referencing the same object.
The final attribute of a RESTful system is that data is transmitted in XML or other HTTP-supported MIME types. The request message can send the version and type accepted by the client, while the server response message sends the version and type of the response data.
Create a database on MySQL Workbench
To create a database, log into MySQL Workbench and use the following command:
CREATE DATABASE `concertDB` ;
If there are multiple schemas or databases, use the following command to be on the correct schema
use concertDB;
Then, create a table named Concert that contains columns to store the concert id, artist name, and concert location.
CREATE TABLE Concert (
ConcertID int,
ArtistName varchar(255),
Location varchar(255)
);
To insert data into the newly created database, use the following command, later we will use this data to display on the web page.
INSERT INTO Concert VALUES(1, "John", "Melbourne");
INSERT INTO Concert VALUES(2, "Jane", "Sydney");
Install required modules
In order to display the database results on the web page, we need to host a RESTful service to perform CRUD operations. To do this, we need to create a new folder called concertAPI using the following command. Open PowerShell or Terminal and enter the following command:
mkdir concertAPI
Then, navigate to the newly created folder concertAPI using the following command
cd concertAPI
We will need to install the following three modules.
express: used to create RestAPI’s
npm install express
MySQL2: Connect to a MySQL database to perform CRUD operations
npm install mysql2
body-parser: Parse incoming requests into javascript objects
npm install body-parser
Now create a new package.json file using the following command
npm init -y
Create database connection
The next step is to establish a database connection. Two files will be created, one to store the database details and another to create the database connection.
The first file is db-details.js, which contains information about the database such as host details, username, password, and database name.
The purpose of module.exports is to use the file contents anywhere in the folder, for example by calling the details from another file.
module.exports = {
host: "localhost",
user: "root",
password: "password",
database : "concertDB"
};
Second, there is a file called database.js that contains information about creating a database connection. This file will import the database details specified in the db-details.js file. To do this we need the following in database.js:
var dbDetails = require("./db-details");
Then, import all other required modules.
var mysql = require('mysql2');
var bodyParser = require('body-parser');
var http = require('http');
Subsequently, we will create a new method called getConnection(), which returns the createConnection() function in mysql2. When creating a connection we need to provide an object containing the database details. These details can be found in db-details. The db-details file has been imported.
The getConnection() method is an anonymous function we created dynamically. It returns a function that requires host, username, password, and database details as parameters. By using this function, we get the database information from db-details instead of hardcoding them. By doing this, these details can be easily identified and modified.
module.exports = {
getconnection: ()=>{
return mysql.createConnection({
host:dbDetails.host,
user:dbDetails.user,
password:dbDetails.password,
database:dbDetails.database
});
}
}
Hosted RESTful API
As the next step, we will create a controller that hosts the RESTful API. The RESTful API is implemented using the database module created above together with the router provided by the Express module. Routing simply maps URLs to our RESTful endpoint methods.
We will follow the Express convention and create a new folder using the following command:
mkdir controllerAPI
Please create a api-controller.js
new file called and use the following code to import the database module we created in order to gain access to the database.
var dbcon = require("../database");
In order to create a new connection we have to call getconnection(). This will allow you to connect to the MySQL database.
var connection = dbcon.getconnection();
Once the connection is established, we need to open the connection to access the database using the following command
connection.connect();
If it is not already imported, import the express module
var express = require('express');
In order to map RESTful endpoints you need to call Router() after getting the express module
var router = express.Router();
Using the router functionality, all necessary http methods such as get, post, put and delete will be enabled. We will use get() to send the URL and an arrow function to handle the request and response. Using the query() function, the SQL query is passed as the first parameter and the second parameter is used for error handling.
router.get("/", (req, res)=>{
connection.query("select * from concert", (err, records,fields)=> {
if (err){
console.error("Error while retrieve the data");
}else{
res.send(records);
}
})
})
Export the router we just created.
module.exports = router;
Initialize REST application
As part of initializing the REST application, we need to create a file called `server.js` that contains the necessary directives.
Please include the required modules, such as Express, if you haven't done so already.
var express = require('express');
We will then create an instance of the application which will act as the root of the application where we can configure the application accordingly.
var app = express();
Then, our restful API needs to configure a path
var concertAPI = require("./controllerAPI/api-controller");
Add function use() to match URL and API
app.use("/api/concerts", concertAPI);
Then call the listen() function to listen on port 3060
app.listen(3060);
Finally, if the server runs successfully, use the following command to print a message to the console
console.log("Server up and running on port 3060");
Go to PowerShell or Terminal and enter the following command
node server.js
To view the data in the database, open a browser and enter the following address
http://localhost:3060/api/concerts
Pass details via URL
In order to expose a Restful endpoint that allows the client to pass an id and we retrieve and return concert details based on that id, we will use the same get method we used before. But now, we need to change the URL.
To accept URL parameters or path variables, we will use /:id
, which means whatever the client provides will be bound to the id variable. Using req
a variable, we can retrieve this variable anywhere in the function. Therefore, a where clause should be added to the select query.
router.get("/:id", (req, res)=>{
connection.query("select * from concert where ConcertID=" + req.params.id, (err, records,fields)=> {
if (err){
console.error("Error while retrieve the data");
}else{
res.send(records);
}
})
})
Now to test it, restart the server and insert more data into the database. Then, pass the id to the url as shown below
http://localhost:3060/api/concerts/1
Create: POST method
To insert data using the POST method, server.js
create a app
variable called in express()
. In effect, calling express()
the function app
creates an Express application in the variable (used to launch the Express application). As mentioned above, after getting the express module, we have called Router()
to map the RESTful endpoint. Create three variables in database.js
for the data to be sent and use query()
to execute the SQL query to insert the data.
router.post("/", (req, res)=>{
var ConcertID = req.body.ConcertID;
var ArtistName = req.body.ArtistName;
var Location = req.body.Location;
connection.query("INSERT INTO concert VALUES("+ConcertID+",'"+ArtistName+"','"+Location+"')",
(err, result)=> {
if (err){
console.error("Error while retrieve the data" + err);
}else{
res.send({insert:"success"});
}
})
})
To retrieve the data we need to server.js
include a body-parser
module in .
First, import body-parser
the module:
const bodyparser = require('body-parser');
Then, include the following commands server.js
:
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({extended:false}));
These commands allow the server to parse requested JSON data and URL-encoded data.
In order to check whether the POST method successfully inserted data through the REST API, we will use a tool called Postman, which will be discussed in the subsequent sections.
Use Postman
Conducting API testing is a common practice. With Postman, we can test HTTP requests using a graphical user interface to get different types of responses that need to be verified later. Using this tool, developers can find almost any feature they need.
Please select your preferred platform from the drop-down menu to download and install Postman on your computer at https://www.postman.com/downloads/.
Watch the video below to learn about Postman: https://www.youtube.com/watch?v=E0f9DUEN_jI
Update: PUT method
In order to use the PUT method to update data, we need to call the PUT method of the Express module and the query method of the MySQL module connection at the same time, using the UPDATE SQL statement.
Call the PUT method in the router:
router.put("/", (req, res) => {
var ConcertID = req.body.ConcertID;
var Location = req.body.Location;
connection.query("UPDATE concert SET Location='" + Location + "' WHERE ConcertID=" + ConcertID,
(err, result) => {
if (err) {
console.error("Error while updating the data: " + err);
} else {
res.send({ update: "success" });
}
});
});
In this example we do this by getting the sum req.body
to be updated . Then, use the method to execute an UPDATE SQL statement, updating the specified to the provided value. If the update is successful, we will return a JSON response containing the update success information.ConcertID
Location
connection.query
ConcertID
Location
Delete: DELETE method
In order to delete data using the DELETE method, we need to call the delete method in the router of the Express module and call the query method using the DELETE SQL statement in the connection of the MySQL module.
Call the DELETE method in the router:
router.delete("/:id", (req, res) => {
connection.query("DELETE FROM concert WHERE ConcertID=" + req.params.id, (err, result) => {
if (err) {
console.error("Error while deleting the data");
} else {
res.send({ delete: "Delete Success" });
}
});
});
In this example we use req.params.id
get to delete ConcertID
. Then, use connection.query
the method to execute the DELETE SQL statement concert
to delete the specified from the table ConcertID
. If the deletion is successful, we will return a JSON response containing the deletion success information.