Some may feel a bit of confusion when talking about the front end and backend. Here, we will discuss the steps for building a frontend using React, a backend using Express.js, and connect them together.
The popularity of JavaScript is increasing day by day. If we learned JavaScript, we can develop both the backend and frontend with it. This makes things easier for a full-stack developer.
Prerequisites
Here in this article, we are simply creating an Express backend, a React frontend, and connecting them together. To follow this article, you must have basic knowledge of JavaScript, React, and Express.
I also assume that you are aware of the terms backend, frontend, etc.
What we will learn
After completing this article, we will learn,
- What is Express?
- What is React?
- To create an Express backend
- Create a react frontend
- We will fetch the data from the backend and show it in our React app.
If you are a beginner in React, it’s recommended that you’d start with creating a basic counter app, to-do list application, or an attendance management app that’ll help you get started with React concepts.
Note that, we are only dealing with JSON data in the express backend and connect it to React frontend. If you want to connect a database with the backend, refer to the article, connect MongoDB Atlas With Express Backend.
What is Express JS?
Express JS is a popular unopinionated web framework, written in JavaScript and hosted within the Node.js runtime environment. It is also a modern backend technology and is popular among new developers.
Other than Express, there is a list of frameworks that helps us in backend development. I have listed some of them below.
What is React JS?
React JS is a simple and powerful library that is gaining huge popularity among developers nowadays. The component architecture is making react an easier way of making the complicated web application UIs in record time. Also, the maintenance and bug fixes are simpler because the codes are divided into components.
Because of browser support javascript, there is a huge list of front-end JavaScript development frameworks/libraries. But the popular among them are listed below.
Here we are choosing Express as our backend technology and React as our front-end technology to build a sample application.
Creating a Node/Express Backend
First, we need to create a Backend to take requests from the frontend and send responses according to it.
To get an idea about the express project we are going to build, I have shown the complete file structure of our project below.
Install Nodejs
Node.js actually provides a runtime environment to execute JavaScript code from outside a browser. NPM, the default package manager for Nodejs is used for managing and sharing the packages for any JavaScript project.
Node.js and NPM are used by Express for the management of dependencies and runtime.
Installing Nodejs on our system may differ from our Operating System.
For Windows users, I have already written an article install Node.Js And NPM On Windows 10.
For macOS, use the below link to download and install Nodejs.
https://nodejs.org/en/download/
Ubuntu users can install Node by executing the below commands.
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash - sudo apt-get install -y nodejs
Others follow the below URL for installation steps.
https://nodejs.org/en/download/package-manager/
Install Nodemon
Nodemon is a tool that helps develop node-based applications by enabling the live reloading feature. Starting our Express app with Nodemon will reload the apps if there is a change in the code.
So install the Nodemon tool globally on our system using our Command Prompt/Terminal.
npm i -g nodemon
Create a Project Directory
Create a project directory and navigate to it using our Command Prompt/Terminal. This can also be done using the Graphical User Interface(GUI).
mkdir express-backend cd express-backend
Initialize a Node.js Project
It requires a package.json file inside our project directory to work with Node.js projects. So we need to initialize a Node.js project using the below command.
npm init
Install Express JS
In this project, we are going to make REST APIs using the Express.js framework. So we need to install Express for our project.
npm i express --save
Install Cors
CORS is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options.
npm i cors --save
Install Body-Parser
To handle HTTP POST requests in Express.js version 4 and above, we need to install the middleware module called body-parser. When we don’t use it, we get the raw request, and your body and headers are not in the root object of the request parameter.
npm i body-parser --save
Install Morgan
Morgan is basically a logger, on any requests being made, it generates logs automatically.
npm i morgan --save
So after creating and installing 4 packages, the package.json file looks like the below.
{
"name": "express-backend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"morgan": "^1.9.1"
}
}
Create and Setup the index.js
When initializing NPM, we selected index.js as our entry point(root file). So the app directs to index.js first and so we need to create and configure it.
So, create an index.js file in our project first and import the packages we have installed in previous steps.
const express = require("express");
const app = express();
const cors = require("cors");
const bodyParser = require("body-parser");
const logger = require("morgan");
Now define a port number in which our app needs to be started.
const port = process.env.PORT || 3001;
Use the logger package we have imported to get the log details of our application if needed.
app.use(logger('dev'));
Now use cors to enable Cross-Origin Resource Sharing.
app.use(cors());
Also, use body-parser to handle HTTP POST requests.
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
We did not create any route yet. But in the upcoming steps, it will be made and configured. So just add the below lines in our root file to set up a /players route.
const playersRouter = require("./routes/players");
app.use("/players", playersRouter);
We already defined a port number and it needs to be used when starting our project. So this port number must listen to our application.
app.listen(port, function() {
console.log("Runnning on " + port);
});
Now export the module app we have created.
module.exports = app;
So that the complete index.js file will be the same as below.
// index.js
const express = require("express");
const app = express();
const cors = require("cors");
const bodyParser = require("body-parser");
const logger = require("morgan");
const port = process.env.PORT || 3001;
const playersRouter = require("./routes/players");
app.use(logger("dev"));
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use("/players", playersRouter);
app.listen(port, function() {
console.log("Runnning on " + port);
});
module.exports = app;
Create a dummy database
Some data needs to be sent to the front end with a GET request. Let us create a dummy database dummyDatabase.js, feed some data, and export it.
So create a file dummyDatabase.js and paste the array of objects players in it and export it.
// dummyDatabase.js
let players = [
{ _id: 1, name: "Sachin", runs: "18426" },
{ _id: 2, name: "Dhoni", runs: "10500" },
{ _id: 3, name: "Virat", runs: "10843" }
];
module.exports = players;
If you really want to use a real database in the app, the article Connect MongoDB Atlas With Express Backend will help you with it.
Create Routes
Now we can create routes to handle the requests from the front-end. In this project, we are only dealing with getting the list of players and getting single-player details. So we need two routes.
We need to create a route file where all the functions of players are defined. So create a players.js file inside a directory named routes.
So create a directory named routes and inside it, create a players.js file.
Import express package and put express.Router() in a variable called a router.
const express = require("express");
const router = express.Router();
Now import the dummy database file we have created earlier.
let players = require("../dummyDatabase");
Create a route to get the list of players
We want to get the complete list of players in our database. So we need to create a function to handle GET requests to the route /list.
router.get("/list", async (req, res) => {
try {
res.status(200).json({
data: players
});
} catch (err) {
res.status(400).json({
message: "Some error occured",
err
});
}
});
Now, if we run our backend, the below link will return the complete list of players.
http://localhost:3001/players/list
Create a route to get a single-player details
We got the full player list. Now we need each player’s details. This can be done by passing the id of each player as the API parameter from the frontend.
:id is the player_id passed as the URL parameter. It is used to find a single-player with the _id.
Note:-
The id that we are passing from the frontend can be accessed from here as req.params.id and it needs to convert to the number type before comparing with database _id because the _ids in the database are in the form of numbers.
router.get("/list/:id", async (req, res) => {
let { id } = req.params;
id = Number(id);
try {
let player = players.find(player => player._id === id);
res.status(200).json({
data: player
});
} catch (err) {
res.status(400).json({
message: "Some error occured",
err
});
}
});
So, the below link returns the details of player 3.
http://localhost:3001/players/3
So the complete players.js file will look like below.
// routes/players.js
const express = require("express");
const router = express.Router();
let players = require("../dummyDatabase");
router.get("/list", async (req, res) => {
try {
res.status(200).json({
data: players
});
} catch (err) {
res.status(400).json({
message: "Some error occured",
err
});
}
});
router.get("/:id", async (req, res) => {
let { id } = req.params;
id = Number(id);
try {
let player = players.find(player => player._id === id);
res.status(200).json({
data: player
});
} catch (err) {
res.status(400).json({
message: "Some error occured",
err
});
}
});
module.exports = router;
Running our Backend
So we have created a RESTful API using Nodejs and Express. Now we can run our backend using Nodemon. Nodemon can watch the changes we are adding to our project and update the live server itself.
nodemon index.js
Testing the APIs
So our server is running on port 3001. The recommended method of testing our APIs is with Postman and it can be downloaded using the link below.
https://www.getpostman.com/downloads/
But here, our backend only deals with getting requests without headers. So we can simply test it within our browser.
GET the complete list of players
The API URL below will show the complete list of players as JSON.
http://localhost:3001/players/list
This will return the data of players from our Express backend without a specific format. I am using the JSON Formatter extension in my chrome browser to format the JSON data.
GET a single-player details
To get the details of a single player, we need to pass the id with our API URL. So the below URL will return the single-player( _id: 2) details.
http://localhost:3001/players/list/2
Creating a React Application(Frontend)
So our Express backend is ready and now we can create a React frontend application to connect with this backend.
To get an idea about the React project we are going to build, I have shown the complete file structure of our project below.
Install and Set Up React
We have already installed Nodejs on our system. So we can create a React application using NPX easily.
npx create-react-app react-frontend
If it is hit with any errors, refer to the detailed guides.
After creating a React application, open the project using a code editor. I recommend the VS code for this.
Adding Bootstrap(optional)
This is an optional step for styling our React application by adding Bootstrap CDN to the index.html file inside /public directory.
Under index.html file, add the below lines between <header></header> section.
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"/>
So the complete index.html file will look like as below.
// public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
<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"
/>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
Configure App.js
Now our working area is App.js under the /src directory. First of all, Clear all the contents in App.js first. We can start coding from line 0 onwards.
Import React and Component
At first, we need to import React, useEffect, and useState from the React package.
Here useState allows managing states in a React app and useEffect is a lifecycle method.
import React, { useState, useEffect } from "react";
Create a function App and export it
We need to create a function named App and export it. We are going to code everything inside this function. Because our react app is small, it does not need to divide our project as components.
export default function App() { }
Initialize all the states
So we need states to store data. We need to initialize the below states.
- list: if the state list is true, the list of players component will be displayed.
- card: if the state card is true, the single-player card will be displayed.
- players: this state stores the list array of players from the backend.
- player: this stores a single-player detail from the backend.
const [list, setList] = useState(true);
const [card, setCard] = useState(false);
const [players, setPlayers] = useState([]);
const [player, setPlayer] = useState({});
Fetch the list of players from API and store it in the state
Now we need to fetch the list of players from the API we have created using Express earlier. This data needs to be stored in the state players.
This should be done just after mounting the component. So we are using the lifecycle method useEffect.
useEffect(() => {
fetch("http://localhost:3001/players/list")
.then((response) => response.json())
.then((responseJson) => {
setPlayers(responseJson.data);
});
}, []);
Create a function to handle the view of a single-player card
Now we need to create a function showCard() which handles the view of a single-player detail card. Inside this, it needs to fetch each player detail with the id and store it in a state named player.
This function can also be used for UI functions. Here we make list value false and card value true. This will hide player’s list view and show a single-player card view.
Note:-
We can also implement this feature using React Navigation, but I am not willing to complicate this small project.
let showCard = (id) => {
fetch(`http://localhost:3001/players/${id}`)
.then((response) => response.json())
.then((responseJson) => {
setPlayer(responseJson.data);
setList(false);
setCard(true);
});
};
Create a function to handle the view of the player’s list
We have a Back button in card view and pressing it will call a function named showList() where it makes card value false and list value true. This will show players’ list view and hide the single-player card view.
let showList = () => {
setCard(false);
setList(true);
};
Start coding the view part
Now we can start coding the view part where we deal with some HTML code to design our web page.
This should be done inside a return as below.
return (
<div className="container">
...
</div>
)
We need to add two UI components. The list view and the card view.
Set up the list view to show players list
Show this list view only if the state list is true. In this situation, map through the array stored in the state players and show each player name inside the map function.
Also, when clicking each name, there have to execute the function showCard(). We have to pass the player id with this function because the data needs to be fetched from backed and shown in the card.
{list ? (
<div className="list-group">
{players.map((player) => (
<li
onClick={() => showCard(player._id)}
className="list-group-item list-group-item-action"
>
{player.name}
</li>
))}
</div>
) : null}
Set up the card view to show a player detail
Show this card view only if the state card is true. In this situation, show details in the player state.
{card ? (
<div class="card" style={{ width: "18rem" }}>
<div class="card-body">
<h5 class="card-title">{player.name}</h5>
<p class="card-text">{player.runs}</p>
<div onClick={() => showList()} class="btn btn-primary">
Back
</div>
</div>
</div>
) : null}
So the complete App.js file will look like below.
// src/App.js
import React, { useState, useEffect } from "react";
export default function App() {
const [list, setList] = useState(true);
const [card, setCard] = useState(false);
const [players, setPlayers] = useState([]);
const [player, setPlayer] = useState({});
useEffect(() => {
fetch("http://localhost:3001/players/list")
.then((response) => response.json())
.then((responseJson) => {
setPlayers(responseJson.data);
});
}, []);
let showCard = (id) => {
fetch(`http://localhost:3001/players/${id}`)
.then((response) => response.json())
.then((responseJson) => {
setPlayer(responseJson.data);
setList(false);
setCard(true);
});
};
let showList = () => {
setCard(false);
setList(true);
};
return (
<div className="container">
{list ? (
<div className="list-group">
{players.map((player) => (
<li
onClick={() => showCard(player._id)}
className="list-group-item list-group-item-action"
>
{player.name}
</li>
))}
</div>
) : null}
{card ? (
<div class="card" style={{ width: "18rem" }}>
<div class="card-body">
<h5 class="card-title">{player.name}</h5>
<p class="card-text">{player.runs}</p>
<div onClick={() => showList()} class="btn btn-primary">
Back
</div>
</div>
</div>
) : null}
</div>
);
}
Running our Frontend
We created a React frontend successfully and now it can be started using the following command.
npm start
This opens up our application in port 3000 and can be accessed with the below URL.
http://localhost:3000
GitHub
The complete project we have made is uploaded to GitHub for reference.
Code for the Express Backend:-
https://github.com/techomoro/SimpleExpressBackend
Code for the React Frontend:-
https://github.com/techomoro/SimpleReactFrontend
Summary
So, here we discussed the steps for creating a React frontend, an Express backend, and connecting them together. We also added the GitHub repositories of both projects in this article.
Thank you for sharing and it greatly helped me.
With zero knowledge about Express and React, I was browsing the internet to do a sample application. In most of the blogs, they configured both in the same application. I couldn’t keep my application with both Express and React running together. I didn’t even understand that one is used as a server-side component and the other is the client technology. Your blog came to rescue. I could understand a lot from your other blogs too. Just want to let you know how much it was helpful.
Hi
I am getting the error
Proxy error: Could not proxy request /api/v1/verifier from localhost:3000 to http://localhost:1105/.
See https://nodejs.org/api/errors.html#errors_common_system_errors for more information (ECONNREFUSED).
I could run it locally on Windows but not on an Ubuntu server
The first error is “Invalid Header” for development server xxx:3000
And the next error after moving to the production server
npm run build
npm install -g serve
serve -s build
is App.js:15 GET http://localhost:3001/players/list net::ERR_CONNECTION_REFUSED
What should I configure on Ubuntu so that Front End can access Back End ?
I can access the Back end from the command line using curl
root@:~# curl -X GET http://localhost:3001/players/list
{“data”:[{“_id”:1,”name”:”Sachin”,”runs”:”18426″},{“_id”:2,”name”:”Dhoni”,”runs”:”10500″},{“_id”:3,”name”:”Virat”,”runs”:”10843″}]}
It is the front end that can not access – what configuration or security should I enable for the 2 servers to see each others on the same machine ?
This was fabulous. Thank you. I have been playing around with integrating something with AWS when I really needed to start here and now the other stuff has fallen into place.
Brilliant post, you have a video?
No sir