* * *

This article is the second in the series of 3 articles on Node.js. You can view the first one here:- http://aasf.in/aasf/postdetails.php?link=66

This article will help you set up a server on Node.js and show you how you can serve requests which you receive from the client side. We will also look into interaction with a MySQL database.

 

We will first be setting up a MySQL workspace in our systems so that we can interact with the database with the help of our server.

We will be installing the MySQL server and MySQL workbench to setup our MySQL workspace. As I did in my previous article, I would strongly recommend you to use a Linux Operating System for development. 

In case you're using windows, please follow this video in order to setup your MySQL workspace:- https://www.youtube.com/watch?v=WuBcTJnIuzo

For Linux users(Ubuntu in specific), first install the MySQL server by following this video:- https://www.youtube.com/watch?v=yRDVDMHoWLA (Please watch the video till the end and follow every instruction exactly as shown in the video). After this is done, install MySQL workbench by following the commands in this artice:- https://www.linode.com/docs/databases/mysql/install-and-configure-mysql-workbench-on-ubuntu/ (The OPTIONAL part in this article may be skipped)

If you need to brush up on your SQL skills, please check out this video before proceeding further:- https://www.youtube.com/watch?v=zbMHLJ0dY4w

 

Alright, now that we have our MySQL workspace ready, let's proceed further.

The whole workflow that we will be following for this article is given at https://github.com/GunaShekar02/Web-Week-2020/blob/master/backend/workflow-pst.txt. I will be constantly referring to line numbers from this file, so please have this page opened in a separate tab.

 

Firstly, let's initialise our project. Create a new folder named "WebWeekTutorial" using the command

mkdir WebWeekTutorial

and then change directory by running "cd WebWeekTutorial" and then run the following command to initialize your project : 

npm init

 Accept the default entries for all of the prompted fields by pressing enter except for "entry point". Type "app.js" when you're asked to enter the entry point for your project.

Now open this directory in your text editor by running "code ." if your editor is VSCode, "subl ." for Sublime, "atom ." for Atom. It is highly recommended you use VSCode(download here: https://code.visualstudio.com/download)

You must be seeing a "package.json" file with the information related to your project, this shows your project has been successfully initialised.

We will be needing express for our project(you can read about express in the previous article, the link to which is given at the beginning of this article), so install it by typing 

npm install express

in your terminal(Please ensure you're in the correct directory while running these commands, it is a common error that people enter these commands in the wrong directory and complain and sometimes abuse node/npm/ubuntu etc. for it).

To check if express was installed properly, check the "dependencies" attribute in your package.json file, and you should see express over there.

 

Create a new file named "app.js" and pase the following code in it:- 

const express = require("express");

const app = express();
 

const PORT = 5000;
 

app.listen(PORT, console.log(`Server started on port ${PORT}`));

and then run "node app.js" in your terminal. You should see "Server started on port 5000" and when you open "localhost:5000" in your browser, you should see "Cannot GET /".

So we have successfully started our server, now let's start serving requests which our server receives.

 

Before that, you need to know that there are 4 main types of requests a client can send to a server, they are Create, Read, Update, Delete, and together they are usually referred to as CRUD Operations. Corresponding to each of these operations, there are HTTP verbs and the server gets to know the type of request the client is sending using these verbs. These verbs corresponding to CRUD operations are:-

Read:- GET
Create:- POST
Update:- PUT
Delete:- DELETE

 

Whenever you open a website on a browser, you're basically trying to read the data on that website, hence, by default, when you open a website, a GET request is sent to its server.

Before the line where you declare the PORT number, add the following code:- 

app.get("*", (req, res) => {

res.status(404).send("You did something wrong!");

});

(PS : The editor I'm writing this article in automatically removes indentation, so please forgive me for not indenting the code here, but I request you(please please please!) indent your code in your text editor. There are readily available code formatters available which automatically indent your code, but that is for another article.)

Now restart your server(whenever I say "restart your server", I mean close your current server by pressing ctrl+C and then running "node app.js" to start the server again).

Now open your browser and go to "localhost:5000". You must be seeing  "You did something wrong!".

Let's break it down line by line.

Express allows you to handle incomming requests very smoothly by providing you with in-built functions for the same.

app.get function is used to listen to a GET request that your server receives and perform required operations.

The first parameter that this function takes is the "route" on which it should be listening for requests. A "route" is basically an "endpoint" in your website. For example, you would want to show a login page at "localhost:5000/login", therefore, "/login" here is your "endpoint. and if you pass "/login" as the first parameter to app.get function, it will listen to all the GET requests sent to the "/login" endpoint, i.e., whenever you open "localhost:5000/login", this function will be executed.

Here, we gave our first parameter as "*". * basically means anything, so any GET request to your website will now be served over here.
The second parameter received by this function is a callback function(learn about callbacks here:-  https://www.youtube.com/watch?v=pTbSfCT42_M). 

WHENEVER A GET REQUEST IS RECEIVED BY YOUR WEBSITE AT ANY "ENDPOINT", THIS CALLBACK FUNCTION WILL BE EXECUTED.

This callback function implicitly receives 2 parameters, first, a request object and second, a response object. The request object is what is given to us by the client and the response object will be used by us to send any response to the client.

res.status(404).send("You did something wrong!"); :-

If you want to send any data to your client, you will have to use the send function which is a part of the response object you received as a parameter in the callback function. Therefore, by executing "res.send("Something")", the client will be able to see "Something" when they send a get request to that endpoint. I'm guessing you're familiar with http status codes(for eg., 404 for "not found", 200 for "ok" etc.. An extensive list of status codes can be found at https://en.wikipedia.org/wiki/List_of_HTTP_status_codes). By res.status(404).send("You did something wrong!"), you are adding a status code 404 meaning "Not found" to your response object and sending a message along with it.

 

At this point, I'd like to stop and ask you guys to install POSTMAN if you haven't already:- https://www.postman.com/downloads/

Postman is an application using which we can test our server and its functions. This application is exactly like a real life postman, you give him an address(an endpoint), your give him your letter(your request), he delivers it to the destination, and assuming the destination owner wants to send you a letter in return(your response), he collects it and brings it back to you. (Now that I read that sentence, it's not exactly like a real life postman, but you get the point).

Now open Postman and click on the "+" icon in the tab bar to open a new tab. You must be seeing something like this:- 

https://drive.google.com/open?id=1fRkgEXIYccNUxOGAf8FWNkFCoWcqNrTl

Ensure that the request type is "GET", change it to GET if it is anything else, and type "http://localhost:5000" in the url box, and click on "Send". You should see something like this:-

https://drive.google.com/open?id=1ydNxImEXY649PrgNuYq7yN_44_XNHCFt

From now on, we will be sending requests to our server using Postman.

 

Suppose a user tries to login, he must be sending his email and password to the server, right? How does the server receive these details? We want to "embed" the details into the "request body". Recall that we're receiving a "request object" as one of our parameters in the callback function. So if somehow we can include the details sent by the client into this object, we can easily access it. Think of it as placing a letter inside an envelope so that the letter is safe inside the envelope and the receiver can open it and read the letter easily. This work is done by a library called as Body Parser. Run "npm install body-parser" in your terminal. MAKE SURE YOU HAVE STOPPED YOUR SERVER BEFORE DOING THIS. AND PLEASE DO NOT RUN 2 SERVERS SIMULTANEOUSLY IN 2 TERMINALS. Only run 1 server at a time, and always remember to turn off the server by pressing ctrl+c before starting it again.

 

So we will be building the backend for a CONTACTS application, which will allow users to login and register, add contacts, edit, delete contacts and view the list of their contacts.

To avoid code congestion, we will divide this whole project into two parts, one where will will serve requests related to login, signup and user related activities such as displaying that particular users' contacts and the other where we will serve requests related to anything else. We will be writing code for each of these in separate files so that our code is kept clean.

Now in the WebWeekTutorial directory, create a new folder named "routes" and in the routes folder, create 2 files, "index.js" and "users.js".

In your "app.js" file, replace the whole code with lines 6-23 from this file:- https://github.com/GunaShekar02/Web-Week-2020/blob/master/backend/workflow-pst.txt. I will refer to this file as the "workflow" file from now on.

Now that you know what Body Parser does, lines 10-11 in the workflow file are just the implementation of the same. They help in embedding the request details into the request object received by our callback function.

Lines 13 and 15 are basically acting like a traffic police. They're saying that whenever you receive any request at the "/<anything>" endpoint, go to index.js to find the functionality for these requests, and whenever you receive any request at the "/users/<anything>" endpoint, go to users.js to find the functionality for these requests. Here, <anything> can even be an empty string. For example, when the users goes to "localhost:5000/users/login", the app.use statement first asks the server to check the users.js file, where will be writing the code to serve requests at "/login" endpoint.

Now let's setup our database connection.

Go to the MySQL Workbench and you should see something like this(UI might be different with different versions):-

https://drive.google.com/open?id=1qPtUkhj6ldhuML7zsmwSsQWeFbksSldu

Click on the "+" icon beside MySQL Connections. Enter the "Connection Name" as "webweek", let the user remain root, click on "store in keychain" beside password and enter the root password which you set while installing mysql server(or workbench in case of windows). Now click on "Test Connection" and you should see something like this:-

https://drive.google.com/open?id=1h_ABF4mq-IPn2PTOkOtKGEYLfBDf3u3C

Now click on "OK" in both the pop ups and double click on the newly created connection and you should see something like this:-

https://drive.google.com/open?id=1QfovcAL6nKuY8pR7NjAWopvsG1o3ZWdx

In the editor, type "CREATE database webweek;" and click on the execute button(the execute button is the lightning button present just above the editor and below the tabs bar). You should see an acknowledgement to this execution in the output below. 

Now go to the WebWeekTutorial directory and create a folder named "db" and within it create a file named "db.js" and paste the following code in it:-

const mysql = require("mysql");

 

const mySqlConnection = mysql.createConnection({

host: "localhost",

user: "root",

password: "ENTER YOUR PASSWORD HERE",

database: "webweek"

});

 

mySqlConnection.connect(err => {

if (err) console.log(err);

console.log("Database Connected!");

});

 

module.exports = mySqlConnection;

In the password attribute, please enter your root password which you earlier used to create the MySQL connection. Please ensure that you have created the database before pasting the above code and also check the spelling of the database, as mysql won't create a new database if it doesn't find one with the same name, it will rather simply throw an error. Similar is the case with tables which we will create below, ensure you create the tables in the workbench before you paste the related code in the files.

Now go to the db folder and run "node db.js" and you should see "Database Connected!" if there was no error in connecting to the database. In case you see that any error was logged in the console, please copy the error, paste it in google search and I'm sure you'll find a github or stackoverflow link providing the solution to your error.

mysql.createConnection establishes a connection between your server and the database. You can think of it as plugging in your charger into a power socket to establish a connection.

mySqlConnection.connect is like turning the switch on after you have connected your charger, so you're making that connection active.

 

We need to install one more library called bcrypt. Bcrypt is an encryption library which we will use to encrypt passwords. Storing user passwords as plain texts in our database is very dangerous, hence we encrypt or "hash" the password before storing it into the database. This hash is irreversible, that means, once we convert some text into a hash, we cannot get the text back from the hash. We won't go deep into hashing in this article. 

Run "npm install bcrypt".

Windows users ran into errors while installing bcrypt, so please refer to this page for the solution if you run into any error at this point:- https://stackoverflow.com/questions/29320201/error-installing-bcrypt-with-npm.
If you're following the first solution, do not forget to replace bcrypt with bcryptjs wherever we will be using it in our project(This solution is recommended). If you're using the 2nd solution and the terminal is stuck at a point and not moving ahead when you're running those commands, stop the process using ctrl+c, open control panel and uninstall python(search on google about how to do this) and re-run the commands and it should work now.

Now go to routes/index.js and paste lines 46-51 from workflow file in it. Paste lines 56-70 from workflow file into routes/users.js file.

Go back to WebWeekTutorial folder in your terminal, ensure any previously started servers are stopped, and run "node app.js" to restrart the server. Now you should see:-

Server started on port 5000
Database Connected!

If this is the case, you're good to go.

 

Now if you open "localhost:5000" on your browser, you will see "home-page". To understand why, go to routes/index.js. Previously in app.js, we mentioned that any request at "localhost:5000/<anything>" endpoint should be searched for in the routes/index.js file. As I said <anything> can be empty as well, therefore, when we enter "localhost:5000" in our browser, a GET request will be sent to the server at the "/" endpoint. The server will look at the routes/index.js file for the corresponding functionality.

express.Router() initialises a router which will act as a traffic police within this file, and help take care of different types of queries in different functions. You can see in routes/index.js file that when we receive a request at the "/" endpoint, we must send "home-page" with a status code of 200, meaning "OK" to the client, and that is what is reflected in your browser.

Now go to Postman and enter "http://localhost:5000/users/login" in the url bar and hit Send.

You should be seeing "login page here!" in the response tab. To understand why, go through the routes/users.js file and it should be pretty straightforward now. Don't worry about the extra things which have been included in this file, we will look into it later on.

So far, we set up our server,  setup the connection to our database, and setup our router to serve different types of request.

 

Now go to routes/users.js and paste the followin lines:-

router.post("/register", (req, res) => {

const { name, email, password, password2, phone } = req.body;

let errors = [];

 

if (!name || !email || !password || !password2 || !phone) {

errors.push({ msg: "Please enter all fields" });

}

 

if (password != password2) {

errors.push({ msg: "Passwords do not match" });

}

 

if (password.length < 6) {

errors.push({ msg: "Password must be at least 6 characters" });

}

mySqlConnection.query(

"SELECT * FROM users WHERE email = ?",

[email],

(err, rows) => {

if (err) res.status(500).send(err);

else if (rows.length) errors.push({ msg: "Email already exists" });

else if (errors.length > 0) {

res.statusCode = 400;

res.send(errors);

} else {

pwdHash = bcrypt.hashSync(password, 10);

var sql = `INSERT INTO users (name, email, phone, pwdHash) VALUES ?`;

const values = [[name, email, phone, pwdHash]];

 

mySqlConnection.query(sql, [values], function(err) {

if (err) res.status(500).send(err);

else res.status(200).send("successfully registered");

});

}

}

);

});

and lines 114-135 from workflow file above the module.exports statement. PLEASE ENSURE THAT YOUR LAST STATEMENT IN THIS FILE IS "module.exports = router;", all code has to be written before this statement.

The code you wrote above is to serve POST(which corresponds to create) requests coming at the "/users/register" and "/users/login" endpoints.

Go to MySql Workbench, clear the editor, type the following lines and click on execute:-

use webweek;
create table users(id int auto_increment primary key, name varchar(255), email varchar(255), pwdHash CHAR(60), phone char(10));
 

This will create a table named users in the webweek database with the given attributes. (TIP : TEXT datatype can be used to store long paragraphs of data). I'm assuming you understand every bit of the above queries, if not, please watch a few videos on youtube to brush up on your SQL skills.

Let's go through the register function line by line. In the first line of the register function, I am "extracting" the name, email, password, password2 and phone "properties" from the "req.body" object. As I mentioned earlier, the body parser places the data we send with the request into the request body and this request body is accessible as req.body. This extraction of individual properties from an object is called "Object Destructuring" in Javascript(You can learn more about this at https://www.youtube.com/watch?v=G4T2ZgJPKbw). So now I have variables named name, email, password, password2 and phone with the data which was sent with the request(we will perform this request soon, for now, assume we have this data). The first few lines of the register route function should be pretty intuitive, we're just checking for a few errors, and if we receive any errors, we're pushing them into an array.

Remember we had exported the mySqlConnection from db/db.js file? We will be using it here to perform queries to the database. The mySqlConnection.query function takes 3 parameters. The first parameter is a MySQL query, and wherever variables are used, we will use a "?" in this query string. This is similar to using "%d" in place of integer values in C. The second parameter is an array which contains the variables which have to replace the "?" in the query string. Therefore, in the first query string "SELECT * FROM users WHERE email = ?", the "?" will be replaced by [email] which is passed as the second parameter. The third parameter is a callback function, where we receive 2 parameters, err and rows. If there was an error performing this query, we will have some error in this err object and if there wasn't any errors, we will receive the rows which were returned by the MySQL query.

We performed this query to check if there was any other user already existing with the same email id. If there was one, we add this error to the array of our errors and send these errors back as a response. So if there is already a user existing with the given email id, a row would have been returned, hence we check if the length of the rows array is greater than zero, and perform operations accordingly. res.statusCode is another way in which you can set the status code for your response. 

If there is no already existing user with the same email id, we proceed to register this user into our database.

pwdHash = bcrypt.hashSync(password, 10); is used to create a "hash" or "encrypt" our password. 
The next two lines have an INSERT query and corresponding variables which have to be inserted.

 

Restart your server.

Now go to Postman, change the "GET" type to "POST" by clicking on the GET tab beside the URL box, and enter "http://localhost:5000/users/register" in the URL box. Below the URL box, you will find "Body", this is where we will enter our details. Click on Body and select "raw" in the buttons given below "Body". At the right end of this row, you will find a dropdown which says "Text". Click on that dropdown and change it to "JSON". Now in the editor given below that row, enter the following lines:-

{
    "name" : "YOUR NAME",
    "email" : "something@abc.com",
    "password" : "secure",
    "password2" : "secure",
    "phone" : "1234567890"
}

After doing all of this, the top part of your Postman screen should look something like this:-

https://drive.google.com/open?id=1_J3SGQAXODjXl_e8gsSnla_H5vyRk5Py

Please re-check if you have selected Body>raw>JSON correctly and entered the details correctly. Now click on "Send" and you should see "Successfully Registered" below. Please ensure your MySQL Workbench is running and also your server is running.

Go to your Workbench, clear the editor and type "select * from users;" in the editor and execute. You should see the entry we made in the database. If you don't, please check the terminal where your server is running for any errors. If you're facing any errors, either in your server or in Postman, copy paste that error in google and you should find a solution. I'm currently using Ubuntu 18.04 and have faced 0 errors so far by exactly following the above written steps.

I'm leaving the Login router function for you to read and understand, it's pretty straight-forward, and if you have understood everything written above, you will understand that as well.

const result = bcrypt.compareSync(password, user.pwdHash); in that function is used to compare passwords. As I said, a hash is irreversible, so basically compareSync function takes your text password, hashes it as well, and compares it against the password hash given to it as a second parameter. It returns true if both the hashes match, and false otherwise.

 

Alright, so now it's time for you to learn about "SESSIONS". You might be familiar with this word, and if you code on codechef, it usually asks you to "disconnect a session" as only one session per user is permitted.

So what is a Session? Imagine the case of an appointment with a doctor. When you call the doctor or the receptionist before your meeting, they give you a token number or appointment number, right? So basically they are creating a "session" with a "unique id" for you with the doctor. That appointment number cannot be used by anyone else. The doctor has a list of all appointment numbers, and whenever you visit the doctor with your "unique appointment id", the doctor will check his list of appointments and determine that you are a valid user.

If you have understood the above scenario, then you have understood sessions. Sessions are basically like an appointment with the server. When the server creates a session for you, it returns a unique "session id" to the client side, which will be stored as a "cookie" on your browser. A cookie is just a text file with some data in it. Now whenever you send a request from your browser, this "unique session id" will automatically get attached to the request object which we are receiving on our server side. And from this session id, we can determine if the user sending the request is valid, and also determine who the sender is, because the server(or the doctor) has a list of all session ids and has information about who it belongs to.

 

Now let's add the sessions functionality to our project and see how it is useful.

Paste the following lines in index.js above the module.exports statement:-

router.get('/dashboard', (req, res) => {

res.status(200).send('dashboard')

});

So when we get a request at "/dashboard" endpoint, we will be sending "dashboard" to the client. Go ahead and enter "localhost:5000/dashboard" in your browser after restarting your server. You must be able to see "dashboard" on your screens. But is it alright if anyone accessing the website can see the dashboard? Certainly not. We wish to only allow our logged in users to view the dashboard. To get to know if the user is logged in(or in other words, to get to know if the patient has taken an appointment), we will use sessions.

For this, we will be using a library called express-session. Type "npm install express-session" in your terminal after stopping your server.

Paste lines 145-152 into app.js file from the workflow file. 
These lines will be used to initialise a session. The maxAge property is the time period for which this session will be valid. The value of this property is given in milliseconds. 

Replace the "/register" and "/login" GET routes in users.js file with the lines 158-162 and 165-169 respectively from the workflow file.
As I said, this session will now be available in our request object, which we can access via req.session. In the upcoming lines of code, we'll be assigning a user with a session everytime they login. Therefore, before rendering the login and register data, we're checking if the user already has a session or not. We're sending the data successfully only if the user is not logged in before. Think of it in this way, if the doctor has already given you an appointment, and you're making another call to book another appointment, should the doctor allow you to do so? Of course not, because you already have an appointment. 

Replace the "/login" POST route in users.js file with lines 172-193 in the workflow file. Notice one line in between, where we write "req.session.user = user". Whenever the user logs in, the server automatically creates a session for him/her and we are adding a "user" attribute to that session to check if that user has already logged in or not. Since we're adding this attribute only at the time of login, if we find at any point that "req.session.user" exists, we can be assured that the user is logged in.

Replace the "/dashboard" GET route in index.js file with lines 198-203 in the workflow file. We're now sending the user details which we stored while logging in when a logged in user hits the "/dashboard" endpoint.

Add lines 207-215 to the users.js file above the module.exports statement. These lines are to implement the logout functionality. By logging out, we basically mean to destroy the cookie on the client side which has the session id and also the session stored on the server. So we're basically erasing the appointment number from the patient's memory and also deleting his/her entry in the appointment list of the doctor.

Now restart your server and go to Postman. Go to your Workbench and enter "select * from users" and ensure that the user we previously created exists. In Postman, select "POST" and in URL box type "http://localhost:5000/users/login". In the request body, ensure you have selected raw>JSON and in the editor, type:-

{
    "email" : "something@abc.com",
    "password" : "secure"
}

and click "Send". You should receive your user details as response, and your screen should look something like this:-

https://drive.google.com/open?id=1YWJAx3k2gk8f_1o2pBAm_EVgMSIB_0E8

Now, in the same row where you have "Body", to the right end, you will find a tab called "Cookies", click on it and you should find a pop up like this:-

https://drive.google.com/open?id=1rqVzuODnH8uhEMInw8rdSSHMMyPgonn1

As you can see, a cookie has been added. If you click on that cookie, you will see that it contains the unique session id we talked about and also the date and time when the cookie will expire.

Now try to send a GET request to "http://localhost:5000/users/login", and you must see an error message saying, "nope, logout". This is because this cookie was sent along with your request and req.session.user was found, and hence, the server knew that you are already logged in, and thus it doesn't show you the login page again.

Send a GET request to "http://localhost:5000/users/logout" and check the try sending a GET request to login again, and this should happen smoothly as the existence of the cookie was removed from the server side when we destroyed the session.

 

With this, we successfully completed User Authentication using Express Sessions.

 

Moving ahead, we will now perform the CRUD operations related to the Contacts we earlier talked about. We will setup routes and functions for a user to view his contacts, edit his contacts and delete his contacts.

 

We will create another table called "contacts" to store the contacts of users with "userID" as Foreign Key which will reference to the "id" attribute in the "users" table. Watch this video if you're unsure about what a Foreign Key is and why it is used :- https://www.youtube.com/watch?v=uaRZy-rflRo

Clear the MySQL editor and type the following query to create the contacts table:- 

create table contacts(id int auto_increment primary key, name varchar(255), email varchar(255), phone char(10), relationship varchar(255), userID int, FOREIGN KEY (userID) REFERENCES users(id));
 

In the users.js file, paste lines 223-255 from workflow file above the module.exports statement.

Let's first talk about the "/contacts" POST route. We're first checking if the user if logged in by checking the session. If yes, we're extracting the details of the contact to be stored from req.body and inserting it into the database according to the syntax we earlier discussed. We have to insert this contact in the contacts table and the userID attribute has to refer to the ID of the user who is posting this contact. Recall that we were storing user details in req.session.user when the user logs in, and hence we can get the ID of the user from req.session.user.id (The code from workflow file mentions it as req.session.user.userID, please change it to req.session.user.id instead as we used id as the attribute earlier while creating the table).

If you understood how the POST request to "/contacts" works, the GET request should be quite intuitive, we're just selecting all contacts of that particular user and sending it. 

SELECT * FROM contacts WHERE userID = req.session.user.id means that we're trying to select all contacts where userID is equal to the id of the user requesting the contacts, this will ensure the user receives only his contacts.

Now go to Postman, login to your account by following the steps discussed above, select POST request, enter "http://localhost:5000/users/contacts" in the URL box, and the following lines in the body:- 

{
    "name" : "Contact 1",
    "email" : "contact1@abc.com",
    "phone" : "1111111111",
    "relationship" : "Complicated"
}

and click "Send". You should see a message saying "contact saved". Now perform a GET request to the same URL, and you should see this contact. Add a few more contacts, create more users, add contacts to those users and try getting the contacts of each user. Play around these operations a bit and understand how things are working.

 

Now suppose you want to update a contact. But a user can have multiple contacts, by simply hitting an endpoint like "/users/contacts", you cannot determine which contact you want to update. But we know one thing about a contact, that is an ID, and we also know that the ID is unique, so if somehow we get to know the ID of the contact we want to edit, we can do so very easily. This can be done using "parameters" in the request URL. 

Paste lines 273-295 from workflow file into the users.js file above the module.exports statement.

Observe the endpoint we have written, "/contacts/:contactID". A colon here indicates that it is a variable parameter and will contain some value. This value can be accessed via the request object as req.params.contactID. Now if we want to update the contact whose id is 1, we will send a request to "/contacts/1" and the ":contactID" will be replaced by 1 and req.params.contactID will contain 1. Now consider a situation with 2 users. User 1 has contacts with IDs 10 and 11. User 2 has contacts with IDs 12 and 13. If User 1 sends a request to "/contacts/12", should he be allowed to edit that contact? He should not, because that contact does not belong to him. Hence we first check if there exists a contact with the given contactID corresponding to the logged in user's ID, and only if it does, we will allow the updation of the contact.

The reason why we didn't use a PUT request for an update operation is that unfortunately, HTML forms only allow GET and POST methods to be used, and we cannot send a PUT or DELETE request using HTML forms. We will, as you will see in the next article, trigger all these endpoints from a client side application through HTML forms, and hence we're not using PUT or DELETE requests.

Similar to the update operation, you can also check out the delete operation from the workflow file. The "/update" endpoint given in the workflow file is to update a particular user's details.

 

That brings us to the end of a reaaaaaaaallly long article. Summarizing, we first installed our MySQL Workspace, created a new project using npm init and started a server, installed postman and triggered some test requests from it, setup mysql and worked on endpoints and how to serve requests that we receive on various endpoints.

In the next article we will look into how we can integrate a client side application with our server side using a templating engine called "EJS" or "Embedded JS", and how we can render data dynamically, i.e., how we can show the contacts of only the particular user who is logged in in the contacts page.
Stay Tuned!

 

This series of articles could not have been possible without the invaluable efforts of the co-organizers of Web Week 2020, Mallikarjun Katakam(https://www.linkedin.com/in/katakam-mallikarjun-668096183/) and Shweta Chaurasia(https://www.linkedin.com/in/shweta-chaurasia-419376187/).

 

In case of any queries, you can find me at https://www.linkedin.com/in/guna-shekar-proddaturi/.