Today, we are going to have CRUD operations in NodeJS using readily available libraries on www.npmjs.com
We will learn how to do Create, Read and Delete operation in NodeJS using Locker system used in Banks example.
Locker System:
In Bank, there are fixed number of lockers available which when fulfilled the next customer will be given only when existing customer deallocates his locker. During allocation the nearest or locker with lesser number available will be given to next customer.
# Pre-requisites for the project to run
1. NodeJS installed, for this setup, you can refer internet
2. Editor like Microsoft Visual Studio, Sublime etc.
# Files needed
1. .env – This file contains all the required environment variables which you can modify before starting server
# PORT
PORT=3000
# Number of available parking spaces
LOCKER_SPACE=5
# Locker Full message
LOCKER_FULL=Locker is FULL!!! Please wait until a customer leaves a locker permanently!!!
# No Customer is allocated given locker message
LOCKER_EMPTY=No customer is allocated this locker or Locker doesn't exist!!!
# Locker is empty message
INVALID_CUSTOMER=There is no such customer present at the locker system!!!
2. LockerSystem.js – This file contains actual business logic for Locker system in Banks
3. package.json – This is the configuration file where all needed dependencies and their version details are maintained
{
"name": "nodejs_crud",
"version": "1.0.0",
"description": "This is a NodeJS CRUD operation project for Locker System",
"main": "LockerSystem.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "TechCruds",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"express-rate-limit": "^5.1.3",
"hashmap": "^2.4.0"
},
"devDependencies": {
"dotenv": "^8.2.0"
}
}
# Setting up the environment to run project
Install needed packages using below mentioned command
1. Install express using below command in cmd prompt:
$ npm install express OR
$ npm install express --save (save is used to save this setting for local system)
2. Install express-rate-limit using below command in cmd prompt:
$ npm install --save express-rate-limit
3. Install hashmap package using below command in cmd prompt:
$ npm install hashmap
4. Install dotenv package using below command in cmd prompt: (this is used for creating .env file)
$ npm install dotenv
#Code
1. Allocating a Locker (Create)
//Allocate a locker API
app.post('/allocateLocker', (req, res) => {
console.log("++++++++++++++++++++++++++++Allocating a Locker++++++++++++++++++++++++++++++++");
//Customer Id is assigned to variable
fetchCustomer = req.body.customer;
console.log("========fetchCustomer"+fetchCustomer);
//creating empty map with null values when first customer arrives
if (map.size == 0) {
for (i = 1; i <= lockerSpace; i++) {
key = "A" + i;
map.set(key, "");
//adding empty lockers to array
lockerArray.push(key);
}
}
if (lockerArray.length != 0) {
//sorting lockers as per numbers
lockerArray.sort();
//reversed array to access the nearest locker to be allocated
lockerArray.reverse();
//nearest locker fetched to be allocated to customer
key = lockerArray[lockerArray.length - 1];
//check if any customer is allocated with locker
mapValue = map.get(key);
console.log("========mapValue"+mapValue);
//checking if there's empty locker space inbetween
if (mapValue === null || mapValue === "" || mapValue === undefined) {
//search if customer is present at the locker
arrivedCustomerLocker = map.search(fetchCustomer);
console.log("========arrivedCustomerLocker"+arrivedCustomerLocker);
//check if the customer is not present then add into nearest locker
if (arrivedCustomerLocker == null) {
//if absent add into locker
map.set(key, fetchCustomer);
console.log("========inside if stmt");
//assign key to lockerTaken by customer
lockerTaken = key;
//remove locker from array as it is filled
lockerArray.pop();
}
else {
//Alert that customer is already allocated with given locker
lockerTaken = "The Customer has already been allocated locker " + arrivedCustomerLocker + " !!!"
}
}
}
else {
//Alert that lockers are full
lockerTaken = lockerFull
}
//preparing output JSON response
resJSON = {
"Locker": lockerTaken
}
//sending JSON as API response
res.json(resJSON);
});
2. Deallocating a Locker (Delete)
//Deallocate a Customer API
app.post('/deallocateLocker', (req, res) => {
console.log("++++++++++++++++++++++++++++Deallocating a Customer++++++++++++++++++++++++++++++++");
//Taking locker from input request into variable
fetchLocker = req.body.locker;
//check if this locker has been allocated to any customer or not
mapValue = map.get(fetchLocker);
//checking if there's empty locker or the invalid locker as input
if (mapValue != null && mapValue != "" && mapValue != undefined) {
//Removing customer from that locker
map.set(fetchLocker, "");
lockerArray.push(fetchLocker);
lockerTaken = "The locker " + fetchLocker + " is free for other customer!!!"
}
else {
lockerTaken = "The locker " + fetchLocker + " is either already free or doesnt exists!!!"
}
//Preparing output JSON response
resJSON = {
"Locker": lockerTaken
}
//sending JSON as API response
res.json(resJSON);
});
3. Get Locker and Customer information (Read)
//Get Locker or Customer Information API
app.get('/getlockerandcustomerinfo', (req, res) => {
console.log("++++++++++++++++++++++++++++Get locker or Customer Info++++++++++++++++++++++++++++++++");
//Taking locker or Customer Id from input request into variables
fetchLocker = req.body.locker;
fetchCustomer = req.body.customer;
//If input locker field is not empty take it as input to fetch related Customer info
if (fetchLocker != null && fetchLocker != "") {
finalLocker = fetchLocker;
//Check if locker system contains locker as key
if (map.has(fetchLocker)) {
//Fetch related customer who is allocated this locker
finalCustomerId = map.get(fetchLocker);
}
else {
finalCustomerId = lockerEmpty
}
}
//If input Customer Id field is not empty take it as input to fetch related locker number
else if (fetchCustomer != null && fetchCustomer != "") {
finalCustomerId = fetchCustomer;
//search locker system for customer Id and return the locker
finalLocker = map.search(fetchCustomer);
if (finalLocker == null || finalLocker == ""){
finalLocker = ""
finalCustomerId = invalidCustomer
}
}
else {
finalCustomerId = invalidCustomer
}
resJSON = {
"Locker": finalLocker,
"CustomerId": finalCustomerId
}
//sending JSON as API response
res.json(resJSON);
});
#How to start the NodeJS server?
Follow below steps to start NodeJS server and running the project:
1. Open command prompt
2. Parse till the folder where you have put all 3 above mentioned files.
3. If you want to change any values for the environment variables you can change in .env file before starting server in next step.
4. Run below command to start server
node LockerSystem.js
5. You will see below lines on command prompt:(If you change the port, it will be reflected at 3000)
3000
Listening on port 3000...........
#Steps to run APIs:
1. Open Postman/SoapUI
2. Paste the URL and select method from below as per API
3. Click on “Body” tab, select “raw” and in dropdown “JSON”
4. Paste below JSON snippet as input request to this service:(key will be same; value can be modified to format as “A<number>”)
5. Click on “Send” and check response below inside “Body” tab and dropdown as “JSON”.
API | Allocate a Locker | Deallocate a Locker | Get Locker or Customer information |
URL | http://localhost:3000/allocateLocker | http://localhost:3000/deallocateLocker | http://localhost:3000/getlockerandcustomerinfo |
Method | POST | POST | GET |
Input Request | { | { | { |
#Explanation:
1. Allocate a Locker:
I have created an hashmap with keys having total number of lockers in Bank, for example, for 10 lockers 10 keys with A1…A10 having values set as empty (“”). When I create this hashmap, I have also stored these keys with empty values in an array. Now, first I am checking if lockers are full or not by having check on array length, where zero means locker full and non-zero means there is empty locker available.
After this, I have sort array and then reverse it to have an empty slot, nearest locker for allocation (as there was only array.pop() method which returns last element) this will give me nearest empty locker for allocating next arriving customer. When new customer arrives, I check into map if I have this customer id present or not, if not then I put this customer at the nearest empty locker and remove this locker from array. Creates a JSON response with this locker number mentioned and send it to response.
2. Deallocating a Locker:
After I get locker from input request, I have checked if there’s any customer who is allocated this locker, if yes, I update the locker with empty value and add this locker into array for further empty locker reference with locker is free for next customer message as response. If the locker doesn’t have any customer, I revert with message that “The locker is already free, or the locker doesn’t exist”. The response JSON is created with locker free message and sent to response.
3. Get Locker or Customer information:
In this case, either locker number or customer ID will come inside request JSON. First, I have checked if the locker value is not null then set this as locker for final JSON response and made a check into map if customer Id related to this locker is present if yes, fetched related customer ID as final response, else “No customer is allocated this locker or Locker doesn’t exist!!!” message is sent as response. Second, if we receive customer ID as an input, I searched for locker where this customer is allocated inside map. After this, JSON is created with both the fields and sent as a response.