Table of contents
- Project Introduction
- Setting Up the Project:-
- Bootstrap:-
- Navigation Bar
- Other Components
- URL Box
- Request Type Box
- Content Type Box
- JSON Request Box
- Parameter Box
- Submit Button
- Response Box
- Entire HTML file at a glance
- Entire JavaScript file at a glance
- Show your support by buying me a coffee
- My other digital presence:
Project Introduction
Postman is a popular application programming interface that makes it easy for developers to create, share, test and document APIs. This is done by allowing the users to create and save simple and complex HTTP/s requests, as well as read their responses. It can make various types of HTTP requests like GET, POST, PUT, PATCH, saving environments for later use, converting the API to code for various languages like JavaScript, Python.
The website we are going to build in this tutorial looks like the following:
Setting Up the Project:-
For this project, we will use the VS Code. If you have not installed the Visual Studio Code yet, then click on the link below for download and installation according to your operating system specifications:
For project setup, start by creating a new project folder in VS Code, and inside that project folder, create two empty new files of HTML (filename.html) and JavaScript (filename.js). The Html file is the entry point for our website and contains the HTML code. In this project, we are also using Bootstrap.
Bootstrap:-
Bootstrap is used for applying styling the user interface components. The easiest way to include Bootstrap is to add it from getbootstrap.com/docs/5.1/getting-started/i...
First include the starter template in the HTML file:
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<title>Hello, world!</title>
</head>
<body>
<h1>Hello, world!</h1>
<!-- Optional JavaScript; choose one of the two! -->
<!-- Option 1: Bootstrap Bundle with Popper -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<!-- Option 2: Separate Popper and Bootstrap JS -->
<!--
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js" integrity="sha384-QJHtvGhmr9XOIpI6YVutG+2QOK9T+ZnN4kzFN1RtK3zEFEIsxhlmWl5/YESvpZ13" crossorigin="anonymous"></script>
-->
</body>
</html>
You will find this starter template in the Bootstrap website for which link has been provided above.
Change the title to PostMaster
and the content inside <h1>
tag to Welcome to PostMaster
and enclose it inside <div>
with a class
name of container
<div class="container">
<h1 class="my-3">Welcome to PostMaster</h1>
</div>
Bootstrap is bundled with many components that can be used to provide good user experience and user interactions in a web page. In this project, we are using bootstrap components for making the front end of website. So, let’s start coding!!!
Navigation Bar
A set of buttons or images in a row or column that serves as a control point to link the user to sections on a website. We will copy-paste navbar components from Bootstrap, but we will tweak it a little according to our requirements.
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">PostMaster</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText"
aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarText">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact us</a>
</li>
</ul>
</div>
</nav>
NOTE: By default Bootstrap supports Light mode styling to change it dark mode add classes such as
bg-dark
& navbar-dark
instead of bg-light & navbar-light.
Other Components
Other components of PostMaster
includes URL Box
, Request Type Box
, Content Type Box
, Parameter Box
(This will hide on clicking JSON option in content type), JSON Request Box
(This will hide on clicking parameters option in content type), a Submit
button which will trigger fetch API
and finally a Response
box which will display response of our actions. So, let's look at each components one by one and in detail.
URL Box
This is the area where we will enter the URL of our API
<div class="form-group row">
<label for="url" class="col-sm-2 col-form-label">URL</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="url" placeholder="Enter URL here" />
</div>
</div>
Request Type Box
Using this we will select the type of request GET/POST
<fieldset class="form-group">
<div class="row">
<legend class="col-form-label col-sm-2 pt-0">
Request Type
</legend>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" name="requestType" id="get" value="GET" checked />
<label class="form-check-label" for="get">
GET
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="requestType" id="post" value="POST" />
<label class="form-check-label" for="post">
POST
</label>
</div>
</div>
</div>
</fieldset>
Content Type Box
This Box will specify whether our request is in JSON
format or it's a Custom Parameters
<fieldset class="form-group">
<div class="row">
<legend class="col-form-label col-sm-2 pt-0">
Content Type
</legend>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" name="contentType" id="jsonRadio" value="json"
checked />
<label class="form-check-label" for="json">
JSON
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="contentType" id="paramsRadio"
value="params" />
<label class="form-check-label" for="params">
Custom Parameters
</label>
</div>
</div>
</div>
</fieldset>
JSON Request Box
This Box will accept our JSON
parameters. This will be active only when our content type
is selected as JSON
<div class="my-3" id="requestJsonBox">
<div class="form-group row">
<label for="requestJsonText" class="col-sm-2 col-form-label">Enter Request Json</label>
<div class="col-sm-10">
<textarea class="form-control" id="requestJsonText" rows="3"></textarea>
</div>
</div>
</div>
Parameter Box
This Box will accept our custom
parameters (Parameter Key & Value). This will be active only when our content type
is selected as Custom Parameters
. It will even have a +/-
icon to add or delete extra parameters.
<div id="parametersBox">
<div class="form-row">
<label for="url" class="col-sm-2 col-form-label">Parameter 1</label>
<div class="col-md-4">
<input type="text" class="form-control" id="parameterKey1" placeholder="Enter Parameter 1 Key">
</div>
<div class="col-md-4">
<input type="text" class="form-control" id="parameterValue1" placeholder="Enter Parameter 1 Value">
</div>
<button id="addParam" class="btn btn-primary"> + </button>
</div>
<div id="params"></div>
</div>
Submit Button
Submit button will act as a trigger point for fetching
our API.
<div class="form-group row my-2">
<div class="col-sm-10">
<button id="submit" class="btn btn-primary">Submit</button>
</div>
</div>
Response Box
Response box will contain all the result after fetching the API. It will even display the error if there was any errors while fetching the API.
<div class="my-3" id="responseJsonBox">
<div class="form-group row">
<label for="responseJsonText" class="col-sm-2 col-form-label">Response</label>
<div class="col-sm-10">
<!-- <textarea class="form-control" id="responseJsonText" rows="3">Your response will appear here</textarea> -->
<pre id="responsePre"
class="language-javascript"> <code id='responsePrism' class="language-javascript"> Your response will appear here </code> </pre>
</div>
</div>
</div>
To set the max-height
to the Response Box we can add a little CSS to it.
<style>
#responsePre {
max-height: 500px;
}
</style>
The templates for all the components can be found on
Bootstrap
website. I have provided you with links. It's up to you to dig how much deeper you want.
Entire HTML file at a glance
Below is the code to the entire HTML
files which contains all the above components including Navigation Bar.
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<link rel="icon" type="image/x-icon" href="https://www.postman.com/_ar-assets/images/favicon-1-48.png">
<link rel="stylesheet" href="prism.css" />
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous" />
<style>
#responsePre {
max-height: 500px;
}
</style>
<title>PostMaster</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<a class="navbar-brand" href="#">PostMaster</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarText"
aria-controls="navbarText" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarText">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Contact us</a>
</li>
</ul>
</div>
</nav>
<div class="container">
<h1 class="my-3">Welcome to PostMaster</h1>
</div>
<div class="container">
<!-- URL box -->
<div class="form-group row">
<label for="url" class="col-sm-2 col-form-label">URL</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="url" placeholder="Enter URL here" />
</div>
</div>
<!-- Request type box -->
<fieldset class="form-group">
<div class="row">
<legend class="col-form-label col-sm-2 pt-0">
Request Type
</legend>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" name="requestType" id="get" value="GET" checked />
<label class="form-check-label" for="get">
GET
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="requestType" id="post" value="POST" />
<label class="form-check-label" for="post">
POST
</label>
</div>
</div>
</div>
</fieldset>
<!-- Content type box -->
<fieldset class="form-group">
<div class="row">
<legend class="col-form-label col-sm-2 pt-0">
Content Type
</legend>
<div class="col-sm-10">
<div class="form-check">
<input class="form-check-input" type="radio" name="contentType" id="jsonRadio" value="json"
checked />
<label class="form-check-label" for="json">
JSON
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="contentType" id="paramsRadio"
value="params" />
<label class="form-check-label" for="params">
Custom Parameters
</label>
</div>
</div>
</div>
</fieldset>
<!-- Parameters box - This will hide on clicking json option in content type -->
<div id="parametersBox">
<div class="form-row">
<label for="url" class="col-sm-2 col-form-label">Parameter 1</label>
<div class="col-md-4">
<input type="text" class="form-control" id="parameterKey1" placeholder="Enter Parameter 1 Key">
</div>
<div class="col-md-4">
<input type="text" class="form-control" id="parameterValue1" placeholder="Enter Parameter 1 Value">
</div>
<button id="addParam" class="btn btn-primary"> + </button>
</div>
<div id="params"></div>
</div>
<!-- Json Request box - This will hide on clicking parameters option in content type -->
<div class="my-3" id="requestJsonBox">
<div class="form-group row">
<label for="requestJsonText" class="col-sm-2 col-form-label">Enter Request Json</label>
<div class="col-sm-10">
<textarea class="form-control" id="requestJsonText" rows="3"></textarea>
</div>
</div>
</div>
<!-- Submit button which will trigger fetch api -->
<div class="form-group row my-2">
<div class="col-sm-10">
<button id="submit" class="btn btn-primary">Submit</button>
</div>
</div>
<!-- Response JSON Box -->
<div class="my-3" id="responseJsonBox">
<div class="form-group row">
<label for="responseJsonText" class="col-sm-2 col-form-label">Response</label>
<div class="col-sm-10">
<!-- <textarea class="form-control" id="responseJsonText" rows="3">Your response will appear here</textarea> -->
<pre id="responsePre"
class="language-javascript"> <code id='responsePrism' class="language-javascript"> Your response will appear here </code> </pre>
</div>
</div>
</div>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
crossorigin="anonymous"></script>
<script src="index.js"></script>
<script src="prism.js"></script>
</body>
</html>
JavaScript
We have done adding HTML and CSS using Bootstrap to our projects. Let's add some functionality for the proper functioning of the website.
Hide Parameter Box initially
let parametersBox = document.getElementById("parametersBox");
parametersBox.style.display = "none";
If the user clicks on custom parameters, Hide the JSON box
let paramsRadio = document.getElementById("paramsRadio");
paramsRadio.addEventListener("click", () => {
document.getElementById("requestJsonBox").style.display = "none";
document.getElementById("parametersBox").style.display = "block";
});
If the user clicks on JSON box, hide the custom parameters box
let jsonRadio = document.getElementById("jsonRadio");
jsonRadio.addEventListener("click", () => {
document.getElementById("requestJsonBox").style.display = "block";
document.getElementById("parametersBox").style.display = "none";
});
If the user clicks on + button add more parameters
First let define some utility functions and variables to do so
Utility function to get DOM element from string
function getElementFromString(string) {
let div = document.createElement("div");
div.innerHTML = string;
return div.firstElementChild;
}
Initialize number of parameters
let addedParamCount = 0;
Finally lets write code to populate the custom parameter box using JavaScript
let addParam = document.getElementById("addParam");
addParam.addEventListener("click", () => {
let params = document.getElementById("params");
let string = `<div class="form-row my-2">
<label for="url" class="col-sm-2 col-form-label">Parameter ${
addedParamCount + 2
}</label>
<div class="col-md-4">
<input type="text" class="form-control" id="parameterKey${
addedParamCount + 2
}" placeholder="Enter Parameter ${
addedParamCount + 2
} Key">
</div>
<div class="col-md-4">
<input type="text" class="form-control" id="parameterValue${
addedParamCount + 2
}" placeholder="Enter Parameter ${
addedParamCount + 2
} Value">
</div>
<button class="btn btn-primary deleteParam"> - </button>
</div>`;
//** Convert the element string to DOM node
let paramElement = getElementFromString(string);
params.appendChild(paramElement);
// Add an event listener to remove the parameter on clicking - button
let deleteParam = document.getElementsByClassName("deleteParam");
for (item of deleteParam) {
item.addEventListener("click", (e) => {
// TODO: add a confirmation box to confirm parameter deletion
e.target.parentElement.remove();
});
}
addedParamCount++;
});
If the user clicks on submit button
if the user have specified all the field carefully and entered the correct value in the respective field. Clicking SUBMIT button will fetch the result in the response box
let submit = document.getElementById("submit");
submit.addEventListener("click", () => {
//** Show please wait in the response box to request patience from the user
// document.getElementById('responseJsonText').value = "Please wait.. Fetching response...";
document.getElementById("responsePrism").innerHTML =
"Please wait.. Fetching response...";
//** Fetch all the values user has entered
let url = document.getElementById("url").value;
let requestType = document.querySelector(
"input[name='requestType']:checked"
).value;
let contentType = document.querySelector(
"input[name='contentType']:checked"
).value;
//** If user has used params option instead of json, collect all the parameters in an object
if (contentType == "params") {
data = {};
for (let i = 0; i < addedParamCount + 1; i++) {
if (
document.getElementById("parameterKey" + (i + 1)) != undefined
) {
let key = document.getElementById(
"parameterKey" + (i + 1)
).value;
let value = document.getElementById(
"parameterValue" + (i + 1)
).value;
data[key] = value;
}
}
data = JSON.stringify(data);
} else {
data = document.getElementById("requestJsonText").value;
}
//** Log all the values in the console for debugging
console.log("URL is ", url);
console.log("requestType is ", requestType);
console.log("contentType is ", contentType);
console.log("data is ", data);
//** if the request type is get, invoke fetch api to create a post request
if (requestType == "GET") {
fetch(url, {
method: "GET",
})
.then((response) => response.text())
.then((text) => {
// document.getElementById('responseJsonText').value = text;
document.getElementById("responsePrism").innerHTML = text;
Prism.highlightAll();
});
} else {
fetch(url, {
method: "POST",
body: data,
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then((response) => response.text())
.then((text) => {
// document.getElementById('responseJsonText').value = text;
document.getElementById("responsePrism").innerHTML = text;
Prism.highlightAll();
});
}
});
I have used Prism JS for extra designing and highlighting the JSON text in the response box. For doing so you can visit Prism Website and select the theme and the languages and download the respective JavaScript(prism.js
) and CSS(prism.css
) files and include it in the index.html
of your project.
Prism.highlightAll() is a function used in the project to highlight JSON fonts
If you don't want to download from Prism website or facing difficulties, Below are the direct links to download the specified file and include it in your project.
Entire JavaScript file at a glance
Below is the code to the entire JavaScript
files
console.log("POSTMAN CLONE");
//* Utility functions:
//** 1. Utility function to get DOM element from string
function getElementFromString(string) {
let div = document.createElement("div");
div.innerHTML = string;
return div.firstElementChild;
}
//* Initialize no of parameters
let addedParamCount = 0;
//* Hide the parameters box initially
let parametersBox = document.getElementById("parametersBox");
parametersBox.style.display = "none";
//* If the user clicks on params box, hide the json box
let paramsRadio = document.getElementById("paramsRadio");
paramsRadio.addEventListener("click", () => {
document.getElementById("requestJsonBox").style.display = "none";
document.getElementById("parametersBox").style.display = "block";
});
//* If the user clicks on json box, hide the params box
let jsonRadio = document.getElementById("jsonRadio");
jsonRadio.addEventListener("click", () => {
document.getElementById("requestJsonBox").style.display = "block";
document.getElementById("parametersBox").style.display = "none";
});
//* If the user clicks on + button, add more parameters
let addParam = document.getElementById("addParam");
addParam.addEventListener("click", () => {
let params = document.getElementById("params");
let string = `<div class="form-row my-2">
<label for="url" class="col-sm-2 col-form-label">Parameter ${
addedParamCount + 2
}</label>
<div class="col-md-4">
<input type="text" class="form-control" id="parameterKey${
addedParamCount + 2
}" placeholder="Enter Parameter ${
addedParamCount + 2
} Key">
</div>
<div class="col-md-4">
<input type="text" class="form-control" id="parameterValue${
addedParamCount + 2
}" placeholder="Enter Parameter ${
addedParamCount + 2
} Value">
</div>
<button class="btn btn-primary deleteParam"> - </button>
</div>`;
//** Convert the element string to DOM node
let paramElement = getElementFromString(string);
params.appendChild(paramElement);
// Add an event listener to remove the parameter on clicking - button
let deleteParam = document.getElementsByClassName("deleteParam");
for (item of deleteParam) {
item.addEventListener("click", (e) => {
// TODO: add a confirmation box to confirm parameter deletion
e.target.parentElement.remove();
});
}
addedParamCount++;
});
//* If the user clicks on submit button
let submit = document.getElementById("submit");
submit.addEventListener("click", () => {
//** Show please wait in the response box to request patience from the user
// document.getElementById('responseJsonText').value = "Please wait.. Fetching response...";
document.getElementById("responsePrism").innerHTML =
"Please wait.. Fetching response...";
//** Fetch all the values user has entered
let url = document.getElementById("url").value;
let requestType = document.querySelector(
"input[name='requestType']:checked"
).value;
let contentType = document.querySelector(
"input[name='contentType']:checked"
).value;
//** If user has used params option instead of json, collect all the parameters in an object
if (contentType == "params") {
data = {};
for (let i = 0; i < addedParamCount + 1; i++) {
if (
document.getElementById("parameterKey" + (i + 1)) != undefined
) {
let key = document.getElementById(
"parameterKey" + (i + 1)
).value;
let value = document.getElementById(
"parameterValue" + (i + 1)
).value;
data[key] = value;
}
}
data = JSON.stringify(data);
} else {
data = document.getElementById("requestJsonText").value;
}
//** Log all the values in the console for debugging
console.log("URL is ", url);
console.log("requestType is ", requestType);
console.log("contentType is ", contentType);
console.log("data is ", data);
//** if the request type is get, invoke fetch api to create a post request
if (requestType == "GET") {
fetch(url, {
method: "GET",
})
.then((response) => response.text())
.then((text) => {
// document.getElementById('responseJsonText').value = text;
document.getElementById("responsePrism").innerHTML = text;
Prism.highlightAll();
});
} else {
fetch(url, {
method: "POST",
body: data,
headers: {
"Content-type": "application/json; charset=UTF-8",
},
})
.then((response) => response.text())
.then((text) => {
// document.getElementById('responseJsonText').value = text;
document.getElementById("responsePrism").innerHTML = text;
Prism.highlightAll();
});
}
});
That's all for this project. If you have any doubts at any steps, Please don't hesitate to raise a question in the comments below, I will try to clarify it at the earliest.
Important links associated with this project:
If you ❤️ My Content! Connect with me on Twitter (abhinav_jha07)
Show your support by buying me a coffee
My other digital presence:
Mail: x3vgi9xr@duck.com
GitHub: akj0712
LinkedIn: abhinavjha07
Telegram: abhinav_kumar_jha
More Content at abhinavjha07.hashnode.dev/
Your feedback is more than welcome