avatarBhargav Bachina

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

11028

Abstract

fit:800/1*bkTcOeYRJdLrr5Nd_hZ5aA.png"><figcaption><b>Register Server</b></figcaption></figure><p id="295b">The server name can be anything that you give for your server such as local, dev, test, etc.</p><figure id="e6c7"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*vVLkRQeACC5CCreMYl8vbg.png"><figcaption><b>Server Name</b></figcaption></figure><p id="3f13">Let’s give all the details such as HostName, port, username, etc under the connection tab.</p><figure id="0a25"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*I3vOpryks3Y0vVpuQMuyuw.png"><figcaption><b>Connection Details</b></figcaption></figure><p id="1f5e">Once connected, you can see the details below.</p><figure id="df06"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*hOkgUQPAfFRaVcBEEJxX7Q.png"><figcaption><b>Connected</b></figcaption></figure><h1 id="4542">Create a Database Table</h1><p id="8e86">Let’s create a table by clicking on the Query Tool as below.</p><figure id="844c"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*G9zcISN6p9W5MVx1yF7Omg.png"><figcaption><b>Query Tool</b></figcaption></figure><p id="646c">Let’s run the following query to create the database table.</p> <figure id="d37b"> <div> <div>

            <iframe class="gist-iframe" src="/gist/bbachi/9dbcc0530954f4a8320eda5ecd34b5c3.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><figure id="fb3f"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*UhDo-kz1-rgLB7OUDkTW-w.png"><figcaption><b>Table Created</b></figcaption></figure><h1 id="2673">Building API</h1><p id="f4d8">We have configured PostgreSQL in the previous section, it’s time to build the API. I would recommend you go through two articles posted in the prerequisites section. Let me put those here as well.</p><blockquote id="b207"><p><a href="https://readmedium.com/how-to-build-nodejs-rest-api-with-express-and-postgresql-674d96d5cb8f">How to Build NodeJS REST API with Express and PostgreSQL</a></p></blockquote><blockquote id="2a79"><p><a href="https://readmedium.com/how-to-write-production-ready-node-js-rest-api-javascript-version-db64d3941106">How to write production-ready Node.js Rest API — Javascript version</a></p></blockquote><p id="8628">The starting point of the API is the <b><i>server.js</i></b> file in which we define all the routes and import the express. Here is the file where the nodejs server runs on port 3080 and starts listening for the incoming requests.</p>
    <figure id="0bb1">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/ecbfc405a9add7964d5a154ec9e222cc.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="9a0d">We have defined 4 routes for CRUD operations. Notice that we are using four different HTTP methods for creating, updating, reading, and deleting operations. The request comes to these routes and each route calls the respective method in the controller class. You can read the body of the incoming requests in the req object defined in each route. The result of these methods is a promise based so you need to use <b><i>then</i></b> method to read and send back to the client with the method <code>res.json().</code></p><p id="1269">Here is the controller class in which we are calling the service class with async/await. The async/await is the cleaner way of reading promises. You don’t need async/await here since we are directly returning the result of the service class.</p>
    <figure id="1041">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/cf3d9b47e600f3327715a80c624a8472.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="7cde">Let’s look at the service class in which we call the repository to interact with the PostgreSQL data.</p>
    <figure id="1a77">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/4c0206ee864bf83a8916642f7e9b9ba5.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="375f">You need to know how to configure PostgreSQL Connection in the NodeJS before looking at the repository so that you can read the data from PostgreSQL. Let’s find that out in the following section.</p><h1 id="2632">Configure PostgreSQL In API</h1><p id="e11d">Let’s configure the pg Client from our application. The first thing we need to do is to get the connection string or connection details. You can get it from the properties below.</p><figure id="fc32"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*zO5cRjjRSYR4F1E3w5h6MA.png"><figcaption><b>Connection Details</b></figcaption></figure><p id="e54d">The next thing is to install the pg client with the following command.</p><div id="2696"><pre>// <span class="hljs-keyword">install</span> client <span class="hljs-keyword">and</span> sequelize

npm <span class="hljs-keyword">install</span> pg npm <span class="hljs-keyword">install</span> sequelize</pre></div><div id="dac3"><pre>// <span class="hljs-keyword">node</span><span class="hljs-title">-postgres</span> home page https://<span class="hljs-keyword">node</span><span class="hljs-title">-postgres</span>.com/</pre></div><p id="25f3">Let’s place the connection string and database name in the application properties file as below. You have to URL encode the password if you have any special characters in the password.</p><p id="71de">Here is the configuration file in which you connect to PostgreSQL with the help of the connection string. We are using pg and sequelize to connect with PostgreSQL for all the queries. These tools make it easy for you to interact with PostgreSQL.</p> <figure id="65c3"> <div> <div>

            <iframe class="gist-iframe" src="/gist/bbachi/720d64b801d81ed69278de2548aba8c6.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="c5e8">The next thing we should define is the schema for the database model as below.</p>
    <figure id="9711">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/d00f608146c63195178a8df31e094a8c.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="5ef9">Finally, we have a repository class as below using the above model for the CRUD operations.</p>
    <figure id="5907">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/a3680ab2e51ddf0fd9ad82c03ce831a0.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><h1 id="9bc6">Externalize the Environment Variables</h1><p id="f9aa">We have seen how to configure your PostgreSQL connection in the API. We need to store this kind of configuration outside of your app so that you can build once and deploy it in multiple environments with ease.</p><p id="8bdc">We need to use the <b>dotenv</b> library for environment-specific things. Dotenv is a zero-dependency module that loads environment variables from a <code>.env</code> file into <a href="https://nodejs.org/docs/latest/api/process.html#process_process_env"><code>process.</code>env</a>. Storing configuration in the environment separate from code is based on <a href="http://12factor.net/config">The Twelve-Factor App</a> methodology.</p><p id="6ce0">The first step is to install this library <code>npm install dotenv</code> and put the .env file at the root location of the project</p>
    <figure id="6c23">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/38e674535f4f0851245b98bce36e8e94.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="24f4">We just need to put this line <code>require('dotenv').config()</code> as early as possible in the application code as in the server.js file.</p>
    <figure id="bc51">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/1a29181bbce1029e85af3802504a778f.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="ff93">Let’s define the configuration class where it creates a connection with the connection details from the properties. We are using pg client to connect with PostgreSQL for all the queries. This client makes it easy for you to interact with PostgreSQL. We are fetching the connection details with the dotenv library and connecting it to PostgreSQL with pg client. We are exposing one function from this file connect.</p><p id="0872">Sequelize is a promise-based NodeJS ORM tool for many relational databases such as Postgres, MYSQL, etc.</p>
    <figure id="cd35">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/d2a5ec615c9a8477b5b3369e07bddfb3.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><h1 id="f8b1">Building UI</h1><p id="9e5c">Once you create the separate folder for React code you need to start with the following command to scaffold the React structure with the help of React CLI. We will not build the entire app here instead we will go through important points here. You can clone the entire GitHub Repo and check the whole app.</p><div id="bb4c"><pre><span class="hljs-string">npm</span> <span class="hljs-built_in">create-react-app</span> <span class="hljs-string">ui</span></pre></div><p id="1b49">Here is the index.js file for the app and App Component as the bootstrap component which means this is the first component that loads in the browser.</p>
    <figure id="763a">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/a464fcd3f35291b8ff72bb25d5cea219.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>

Options

    </figure></iframe></div></div></figure><p id="7e21">Here is the starting point of the application in which we define the Home component to load for the path /. You need to import the react-router-dom library for the routing part of the app. The Home page will be loaded when we start the application.</p>
    <figure id="af6c">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/ca05d3eb1c3dee19bc797bf983ef5da1.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="20ac">Here is the Home component. This is a simple application where you add, update, delete tasks. You can go through the GitHub repo to check the rest of the files. We are using two hooks here one is for maintaining the local state and another is for fetching the data from the API.</p>
    <figure id="d1b0">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/0f4dbda7b02c1db0c66605a743557eb1.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="746d">We have another two important components here one is for the createTask Form component and another is for the Tasks table.</p>
    <figure id="be8e">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/b02b50bb1ae61e4f4ff84f6279a642f7.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="66bb">Run the React code in local with the following command which runs on the port <b>3000</b> on localhost. Make sure you are in the root folder of React code which is todo-app here.</p><div id="eefc"><pre><span class="hljs-built_in">cd</span> ui

npm <span class="hljs-built_in">start</span></pre></div><figure id="c9a2"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*VvqnWU7ALoWr_8zacHNXKg.png"><figcaption><b>React Code running on port 3000</b></figcaption></figure><h1 id="0df9">Make API Calls From UI</h1><p id="da95">Here is the service file which calls the API, in this case. We have four API operations to get, add, edit, and delete tasks with root path <b>/api.</b></p> <figure id="8a54"> <div> <div>

            <iframe class="gist-iframe" src="/gist/bbachi/a0118082cfcf01b85b20b4a3cd8b36ab.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="a0eb">From the react components you can call this service to get the data using React Hooks. Here is an example.</p>
    <figure id="4822">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/38cd2ff52039c62e553e0a48e0120f74.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="1811">You can look at the below article for a detailed post.</p><blockquote id="4ea2"><p><a href="https://readmedium.com/how-to-make-api-calls-in-react-applications-7758052bf69">How To Make API calls in React Applications</a></p></blockquote><h1 id="a38d">Development Environment Setup</h1><p id="830b">Usually, the way you develop and the way you build and run in production are completely different.</p><p id="be61">In the development phase, we run the nodejs server and the React app on completely <b>different ports.</b> It’s easier and faster to develop that way. If you look at the following diagram the React app is running on port <b>3000</b> with the help of a webpack dev server and the nodejs server is running on port <b>3080</b>.</p><figure id="9d76"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/0*lMI9mRsPc_cxeqYV.png"><figcaption><b>Development Environment</b></figcaption></figure><p id="d479">There should be some interaction between these two. We can proxy all the API calls to nodejs API. Create-react-app provides some inbuilt functionality and to tell the development server to proxy any unknown requests to your API server in development, add a <code>proxy</code> field to your <code>package.json</code> of the React. Have a look at the package.json below. Remember you need to put this in the React UI package.json file.</p>
    <figure id="8638">
        <div>
          <div>
            
            <iframe class="gist-iframe" src="/gist/bbachi/9ae4dbdb179ca15a5507ee2a7296c262.js" allowfullscreen="" frameborder="0" height="undefined" width="undefined">
          </div>
        </div>
    </figure></iframe></div></div></figure><p id="092c">Now you can run both Reac UI and NodeJS API on different ports and the React Code interacts with the API.</p><div id="67b2"><pre><span class="hljs-regexp">//</span> React Code

cd ui <span class="hljs-built_in">npm</span> install <span class="hljs-built_in">npm</span> start</pre></div><div id="fd78"><pre><span class="hljs-comment">// API code</span> <span class="hljs-keyword">cd</span> api npm install npm <span class="hljs-keyword">run</span> dev</pre></div><figure id="2838"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*j7EWjQuwx76WTOILWDvXHQ.gif"><figcaption></figcaption></figure><figure id="52be"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Yw9Jl54tMWx554iAlW8XUA.gif"><figcaption><b>Network Calls</b></figcaption></figure><h1 id="8c34">Running on Docker Compose</h1><p id="763e">Docker Compose is really useful when we don’t have the development environment setup on our local machine to run all parts of the application to test or we want to run all parts of the application with one command. For example, if you want to run NodeJS REST API and PostgreSQL database on different ports and need a single command to set up and run the whole thing. You can accomplish that with Docker Compose.</p><p id="0865">Coming Soon!!</p><h1 id="0785">Dockerize PERN Stack</h1><p id="9e3c">Docker is an enterprise-ready container platform that enables organizations to seamlessly build, share, and run any application, anywhere. Almost every company is containerizing its applications for faster production workloads so that they can deploy anytime and sometimes several times a day. There are so many ways we can build a PERN Stack. One way is to dockerize it and create a docker image so that we can deploy that image any time or sometimes several times a day.</p><p id="7a2e">Coming Soon!!</p><h1 id="cd22">Linting</h1><p id="8dda">We need to lint our project in that way it’s easier to follow some standards in your project. We will see this in a separate article.</p><p id="2ff9">Coming Soon!!</p><h1 id="ddec">Unit Testing API</h1><p id="3695">There are so many tools out there to unit test your application such as Mocha, Chai, etc. We need a separate article for that to cover different libraries.</p><p id="bfd8">Coming Soon!!</p><h1 id="ff5c">Unit Testing UI</h1><p id="feff">We will see how to unit test with UI with jest library.</p><p id="df2a">Coming Soon!</p><h1 id="f4e4">Integration Tests</h1><p id="27e2">We will use cypress for the integration tests.</p><p id="5773">Coming Soon!</p><h1 id="7c73">Build for production</h1><p id="8004">We have to build the project for production in a different way. We can’t use the proxy object. Here is the detailed article on how to package your app for production.</p><blockquote id="ef07"><p><a href="https://readmedium.com/packaging-your-react-app-with-nodejs-backend-for-production-7ddae2b84f1b">Packaging Your React App With NodeJS Backend For Production</a></p></blockquote><h1 id="3f9a">Demo</h1><p id="9a23">Here is an example of a simple tasks application that creates, retrieves, edits, and deletes tasks. We actually run the API on the NodeJS server and you can use PostgreSQL to save all these tasks.</p><figure id="4530"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*BRzkjumicvmmdiD8Yn_DyQ.gif"><figcaption><b>Example Project</b></figcaption></figure><p id="b68a">As you add users we are making an API call to the nodejs server to store them and get the same data from the server when we retrieve them. You can see network calls in the following video.</p><figure id="7139"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*Yw9Jl54tMWx554iAlW8XUA.gif"><figcaption><b>Network Calls</b></figcaption></figure><h1 id="1f54">Summary</h1><ul><li>There are so many ways we can build React apps and ship them for production.</li><li>One way is to build the React app with NodeJS and PostgreSQL as a database. There are four things that make this stack popular and you can write everything in Javascript.</li><li>The four things are PostgreSQL, React, Express, and NodeJS. This stack can be used for a lot of uses cases in web development.</li><li>We will have two package.json: one for the <b>React</b> and another for <b>nodejs API</b>. It’s always best practice to have completely different node_modules for each one.</li><li>You can get the connection string and configure the NodeJS application to talk to PostgreSQL with pg client, etc.</li><li><b><i>node-postgres: </i></b>Non-blocking Postgresql Client for NodeJS</li><li><b><i>PGAdmin: </i></b>pgAdmin is an Open Source administration and development platform for PostgreSQL</li><li>We need to use the <b>dotenv</b> library for environment-specific things. Dotenv is a zero-dependency module that loads environment variables from a <code>.env</code> file into <a href="https://nodejs.org/docs/latest/api/process.html#process_process_env"><code>process.</code>env</a>. Storing configuration in the environment separate from code is based on <a href="http://12factor.net/config">The Twelve-Factor App</a> methodology.</li><li>In the development phase, we run the nodejs server and the React app on completely <b>different ports.</b> It’s easier and faster to develop that way.</li><li>We need to lint our project in that way it’s easier to follow some standards in your project.</li><li>There are so many tools out there to unit test the API such as Mocha, Chai, etc.</li><li>We can unit test with UI with jest library.</li><li>We will use cypress for the integration tests.</li><li>We have to build the project for production in a different way. We can’t use the proxy object.</li></ul><h1 id="ee08">Conclusion</h1><p id="8b4f">PERN Stack is very good when you want to develop a simple web app and deploy your frontend and backend together. We have seen how to write PERN Stack in detail. In future posts, we will see how to build and deploy the PERN Stack on different Clouds such as GCP, Azure, AWS, etc.</p></article></body>

How To Develop and Build PERN Stack

A step by step guide with an example project

There are so many ways we can build React apps and ship them for production. One way is to build the React app with NodeJS and PostgreSQL as a database. There are four things that make this stack popular and you can write everything in Javascript. The four things are PostgreSQL, React, Express, and NodeJS. This stack can be used for a lot of uses cases in web development.

The entire frontend is written in React and we are using PostgreSQL as a document database. The express and NodeJS are used for the middle layer. In this post, we will see the details and implementation of the PERN Stack. We will go through step by step with an example project.

  • Introduction
  • Prerequisites
  • Example Project
  • Project Structure
  • Install PostgreSQL on Local Machine
  • Install PGAdmin Tool
  • Create a Database Table
  • Building API
  • Configure PostgreSQL In API
  • Externalize the Environment Variables
  • Building UI
  • Make API Calls From UI
  • Development Environment Setup
  • Running on Docker Compose
  • Dockerize PERN Stack
  • Linting
  • Unit Testing API
  • Unit Testing UI
  • Integration Tests
  • Build for production
  • Demo
  • Summary
  • Conclusion

Introduction

As we said earlier, PERN Stack uses four technologies such as PostgreSQL, Express, React, and NodeJS. React is a javascript library for building web apps and it doesn’t load itself in the browser. We need some kind of mechanism that loads the index.html (single page) of React application with all the dependencies(CSS and js files) in the browser. In this case, we are using node as the webserver which loads React assets and accepts any API calls from the React UI app.

PERN Stack

If you look at the above diagram all the web requests without the /api will go to React routing and the React Router kicks in and loads components based on the path. All the paths that contain /api will be handled by the Node server itself.

Prerequisites

There are some prerequisites for this post. You need to have a NodeJS installed on your machine and some other tools that are required to complete this project.

NodeJS: As an asynchronous event-driven JavaScript runtime, Node.js is designed to build scalable network applications.

Express Framework: Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.

node-postgres: Non-blocking Postgresql Client for NodeJS

PGAdmin: pgAdmin is an Open Source administration and development platform for PostgreSQL

PostgreSQL: Open Source relational Database

VSCode: The editor we are using for the project. It’s open-source and you can download it here.

Postman: Manual testing your APIs

nodemon: To speed up the development

If you are a complete beginner and don’t know how to build from scratch, I would recommend going through the below articles. We used these projects from this article as a basis for this post.

How To Get Started With React

How To Develop and Build React App With NodeJS

How to Build NodeJS REST API with Express and PostgreSQL

How to write production-ready Node.js Rest API — Javascript version

Example Project

Here is an example of a simple tasks application that creates, retrieves, edits, and deletes tasks. We actually run the API on the NodeJS server and you can use PostgreSQL to save all these tasks.

Example Project

As you add users we are making an API call to the nodejs server to store them and get the same data from the server when we retrieve them. You can see network calls in the following video.

Network Calls

Here is a Github link to this project. You can clone it and run it on your machine.

// clone the project
git clone https://github.com/bbachi/pern-stack-example.git
// React Code
cd ui
npm install
npm start
// API code
cd api
npm install
npm run dev

Project Structure

Let’s understand the project structure for this project. We will have two package.json: one for the React and another for nodejs API. It’s always best practice to have completely different node_modules for each one. In this way, you won’t get merging issues or any other problems regarding web and server node modules collision. It’s easier to convert your PERN Stack into any other stack later such as replacing the API code with microservices and serving your UI through the NGINX web server.

Project Structure

If you look at the above project structure, all the React app resides under the ui folder and nodejs API resides under the api folder.

Install PostgreSQL on Local Machine

There are so many ways to install PostgreSQL on your local machine from the below link. The Postgres.app is the easiest and fastest one.

https://www.postgresql.org/download/macosx/

You can click on the Postgres.app and download the app from that page.

Postgres.app

You can go through the below installation steps and initialize the Database.

Download and Install Instructions

If everything is successful, you can see the below screen with the database named after the user name on the machine.

Postgres.app

Install PGAdmin Tool

The pgAdmin tool is the open-source administration and development platform for PostgreSQL. You can install this tool from the following location.

https://www.pgadmin.org/
pgAdmin Tool

Once installed, you can open that and connect to the PostgreSQL server with the following credentials. It changes based on your user name folder.

// name of the server
name: local (You can name anything)
// Hostname
host name: localhost
// User Name
username: <user name based on the above postgres.app>
pgAdmin Tool

Let’s connect to the server by clicking on the register as below.

Register Server

The server name can be anything that you give for your server such as local, dev, test, etc.

Server Name

Let’s give all the details such as HostName, port, username, etc under the connection tab.

Connection Details

Once connected, you can see the details below.

Connected

Create a Database Table

Let’s create a table by clicking on the Query Tool as below.

Query Tool

Let’s run the following query to create the database table.

Table Created

Building API

We have configured PostgreSQL in the previous section, it’s time to build the API. I would recommend you go through two articles posted in the prerequisites section. Let me put those here as well.

How to Build NodeJS REST API with Express and PostgreSQL

How to write production-ready Node.js Rest API — Javascript version

The starting point of the API is the server.js file in which we define all the routes and import the express. Here is the file where the nodejs server runs on port 3080 and starts listening for the incoming requests.

We have defined 4 routes for CRUD operations. Notice that we are using four different HTTP methods for creating, updating, reading, and deleting operations. The request comes to these routes and each route calls the respective method in the controller class. You can read the body of the incoming requests in the req object defined in each route. The result of these methods is a promise based so you need to use then method to read and send back to the client with the method res.json().

Here is the controller class in which we are calling the service class with async/await. The async/await is the cleaner way of reading promises. You don’t need async/await here since we are directly returning the result of the service class.

Let’s look at the service class in which we call the repository to interact with the PostgreSQL data.

You need to know how to configure PostgreSQL Connection in the NodeJS before looking at the repository so that you can read the data from PostgreSQL. Let’s find that out in the following section.

Configure PostgreSQL In API

Let’s configure the pg Client from our application. The first thing we need to do is to get the connection string or connection details. You can get it from the properties below.

Connection Details

The next thing is to install the pg client with the following command.

// install client and sequelize
npm install pg
npm install sequelize
// node-postgres home page
https://node-postgres.com/

Let’s place the connection string and database name in the application properties file as below. You have to URL encode the password if you have any special characters in the password.

Here is the configuration file in which you connect to PostgreSQL with the help of the connection string. We are using pg and sequelize to connect with PostgreSQL for all the queries. These tools make it easy for you to interact with PostgreSQL.

The next thing we should define is the schema for the database model as below.

Finally, we have a repository class as below using the above model for the CRUD operations.

Externalize the Environment Variables

We have seen how to configure your PostgreSQL connection in the API. We need to store this kind of configuration outside of your app so that you can build once and deploy it in multiple environments with ease.

We need to use the dotenv library for environment-specific things. Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. Storing configuration in the environment separate from code is based on The Twelve-Factor App methodology.

The first step is to install this library npm install dotenv and put the .env file at the root location of the project

We just need to put this line require('dotenv').config() as early as possible in the application code as in the server.js file.

Let’s define the configuration class where it creates a connection with the connection details from the properties. We are using pg client to connect with PostgreSQL for all the queries. This client makes it easy for you to interact with PostgreSQL. We are fetching the connection details with the dotenv library and connecting it to PostgreSQL with pg client. We are exposing one function from this file connect.

Sequelize is a promise-based NodeJS ORM tool for many relational databases such as Postgres, MYSQL, etc.

Building UI

Once you create the separate folder for React code you need to start with the following command to scaffold the React structure with the help of React CLI. We will not build the entire app here instead we will go through important points here. You can clone the entire GitHub Repo and check the whole app.

npm create-react-app ui

Here is the index.js file for the app and App Component as the bootstrap component which means this is the first component that loads in the browser.

Here is the starting point of the application in which we define the Home component to load for the path /. You need to import the react-router-dom library for the routing part of the app. The Home page will be loaded when we start the application.

Here is the Home component. This is a simple application where you add, update, delete tasks. You can go through the GitHub repo to check the rest of the files. We are using two hooks here one is for maintaining the local state and another is for fetching the data from the API.

We have another two important components here one is for the createTask Form component and another is for the Tasks table.

Run the React code in local with the following command which runs on the port 3000 on localhost. Make sure you are in the root folder of React code which is todo-app here.

cd ui
npm start
React Code running on port 3000

Make API Calls From UI

Here is the service file which calls the API, in this case. We have four API operations to get, add, edit, and delete tasks with root path /api.

From the react components you can call this service to get the data using React Hooks. Here is an example.

You can look at the below article for a detailed post.

How To Make API calls in React Applications

Development Environment Setup

Usually, the way you develop and the way you build and run in production are completely different.

In the development phase, we run the nodejs server and the React app on completely different ports. It’s easier and faster to develop that way. If you look at the following diagram the React app is running on port 3000 with the help of a webpack dev server and the nodejs server is running on port 3080.

Development Environment

There should be some interaction between these two. We can proxy all the API calls to nodejs API. Create-react-app provides some inbuilt functionality and to tell the development server to proxy any unknown requests to your API server in development, add a proxy field to your package.json of the React. Have a look at the package.json below. Remember you need to put this in the React UI package.json file.

Now you can run both Reac UI and NodeJS API on different ports and the React Code interacts with the API.

// React Code
cd ui
npm install
npm start
// API code
cd api
npm install
npm run dev
Network Calls

Running on Docker Compose

Docker Compose is really useful when we don’t have the development environment setup on our local machine to run all parts of the application to test or we want to run all parts of the application with one command. For example, if you want to run NodeJS REST API and PostgreSQL database on different ports and need a single command to set up and run the whole thing. You can accomplish that with Docker Compose.

Coming Soon!!

Dockerize PERN Stack

Docker is an enterprise-ready container platform that enables organizations to seamlessly build, share, and run any application, anywhere. Almost every company is containerizing its applications for faster production workloads so that they can deploy anytime and sometimes several times a day. There are so many ways we can build a PERN Stack. One way is to dockerize it and create a docker image so that we can deploy that image any time or sometimes several times a day.

Coming Soon!!

Linting

We need to lint our project in that way it’s easier to follow some standards in your project. We will see this in a separate article.

Coming Soon!!

Unit Testing API

There are so many tools out there to unit test your application such as Mocha, Chai, etc. We need a separate article for that to cover different libraries.

Coming Soon!!

Unit Testing UI

We will see how to unit test with UI with jest library.

Coming Soon!

Integration Tests

We will use cypress for the integration tests.

Coming Soon!

Build for production

We have to build the project for production in a different way. We can’t use the proxy object. Here is the detailed article on how to package your app for production.

Packaging Your React App With NodeJS Backend For Production

Demo

Here is an example of a simple tasks application that creates, retrieves, edits, and deletes tasks. We actually run the API on the NodeJS server and you can use PostgreSQL to save all these tasks.

Example Project

As you add users we are making an API call to the nodejs server to store them and get the same data from the server when we retrieve them. You can see network calls in the following video.

Network Calls

Summary

  • There are so many ways we can build React apps and ship them for production.
  • One way is to build the React app with NodeJS and PostgreSQL as a database. There are four things that make this stack popular and you can write everything in Javascript.
  • The four things are PostgreSQL, React, Express, and NodeJS. This stack can be used for a lot of uses cases in web development.
  • We will have two package.json: one for the React and another for nodejs API. It’s always best practice to have completely different node_modules for each one.
  • You can get the connection string and configure the NodeJS application to talk to PostgreSQL with pg client, etc.
  • node-postgres: Non-blocking Postgresql Client for NodeJS
  • PGAdmin: pgAdmin is an Open Source administration and development platform for PostgreSQL
  • We need to use the dotenv library for environment-specific things. Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env. Storing configuration in the environment separate from code is based on The Twelve-Factor App methodology.
  • In the development phase, we run the nodejs server and the React app on completely different ports. It’s easier and faster to develop that way.
  • We need to lint our project in that way it’s easier to follow some standards in your project.
  • There are so many tools out there to unit test the API such as Mocha, Chai, etc.
  • We can unit test with UI with jest library.
  • We will use cypress for the integration tests.
  • We have to build the project for production in a different way. We can’t use the proxy object.

Conclusion

PERN Stack is very good when you want to develop a simple web app and deploy your frontend and backend together. We have seen how to write PERN Stack in detail. In future posts, we will see how to build and deploy the PERN Stack on different Clouds such as GCP, Azure, AWS, etc.

Programming
Web Development
Software Development
Software Engineering
JavaScript
Recommended from ReadMedium