Full Stack setup from scratch - Node.js, Express.js, React.js and Lowdb (Part 1)
Tags: node, express, react, lowdb
Published: 2020-03-20 14:26:04

1. [**Setup**](https://dev.to/brunobc/full-stack-setup-from-scratch-node-js-express-js-react-js-and-lowdb-part-1-1dpa)
2. [Filter pages to print](https://dev.to/brunobc/full-stack-setup-from-scratch-node-js-express-js-react-js-and-lowdb-part-2-l3o)
3. [Deploy to Heroku](https://dev.to/brunobc/full-stack-setup-from-scratch-node-js-express-js-react-js-and-lowdb-part-3-1ao0)

First, in command line, let's create a project folder and a package.json file:

```
mkdir node-react-project
cd node-react-project
npm init -y
```

> [package.json](https://docs.npmjs.com/files/package.json)
+ *name* defines the name of the application or package;
+ *version* indicates the current version;
+ *description* is a summary of your application/package;
+ *main* defines the application entry point;
+ *private* (true) prevents your application from being accidentally published to npm;
+ *scripts* defines a set of Node scripts for you to execute;
+ *dependencies* defines a list of installed npm packages as dependencies;
+ *devDependencies* defines a list of installed npm packages as development dependencies;
+ *engines* defines which Node versions this package /application works;
+ *browserslist* is used to tell which browsers (and versions) you want to support;

Now, let's install the project dependencies:

```
npm install --save express body-parser lowdb
```

> [Express.js](https://expressjs.com/) is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
[body-parser](https://www.npmjs.com/package/body-parser) Node.js body parsing middleware. Parse incoming request bodies in a middleware before your handlers, available under the req.body property.
[lowdb](https://github.com/typicode/lowdb) is a small JSON database for Node, Electron and the browser.

Install the development dependencies:
```
npm install --save-dev nodemon concurrently
```

>[nodemon](https://www.npmjs.com/package/nodemon) is a tool that helps develop node.js based applications by automatically restarting the node application when file changes in the directory are detected. 
[concurrently](https://www.npmjs.com/package/concurrently) run multiple commands concurrently.

Then, we have package.json like this:

![](https://raw.githubusercontent.com/brunobc/node-react-project/master/prints/packagejson.png)

Let's create the project scructure:

```
mkdir routes
touch index.js
```

In the index.js we will add the following code:
```javascript
const express = require('express');
const bodyParser = require('body-parser');

const app = express();

app.use(bodyParser.json());

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
  console.log(`app running on port ${PORT}`)
});
```

So, add the "server" entry into the "scripts" section of your package.json:

```javascript
"server": "nodemon index.js"
```
Then, we can execute that script to run backend:

```
npm run server
```

Before starting version control, let's create a .gitignore file in the project's root folder and add the following line:
                                 
```javascript
node_modules
```

After that, create a new repository on [GitHub](http://github.com/) and upload our source code to that.

```
git init
git add .
git commit -m "backend configuration"
git remote add origin https://github.com/brunobc/node-react-project.git
git push -u origin master
```

Now, let's create a frontend with [create-react-app](https://github.com/facebook/create-react-app) and add dependencies:
```
npx create-react-app front
cd front
npm install --save http-proxy-middleware axios
```

>[http-proxy-middleware](https://www.npmjs.com/package/http-proxy-middleware) is a node.js proxying from frontend to backend.
[axios](https://www.npmjs.com/package/axios) is a promise based HTTP client for the browser and node.js.

In client directory /front/src, let's add the file [setupProxy.js](https://create-react-app.dev/docs/proxying-api-requests-in-development/) to proxy from frontend to backend.
```javascript
const { createProxyMiddleware } = require('http-proxy-middleware')

module.exports = function(app) {
  app.use('/api/', createProxyMiddleware({
    target: 'http://localhost:5000',
    changeOrigin: true
  }));
}
```

In the package.json, in the root project, add the scripts:
```javascript
"client": "npm run start --prefix front",
"server": "nodemon index.js",
"dev": "concurrently --kill-others-on-fail \"npm run server\" \"npm run client\"",
"start": "node index.js"
```

To run the project in production, we need to add the following code after ``app.use(bodyParser.json())``, in your index.js file. That will redirect all requests from the frontend.

```javascript
if (process.env.NODE_ENV === 'production') {
  app.use(express.static('front/build'));

  const path = require('path');
  app.get('*', (req,res) => {
    res.sendFile(path.resolve(__dirname, 'front', 'build', 'index.html'));
  });
}
```

Let's create the database file, as required by LowDB, naming it as ``db.json`` in the root project, then let's use [shortid](https://github.com/dylang/shortid) to create the user' ids.
```
touch db.json
npm install --save shortid
```

In db.json:
```javascript
{
  "users": []
}
```
Now let's create the routes for our backend API.
We added the userRoutes.js file to the /routes directory. Then, add the following snippet:

```javascript
const low = require('lowdb');
const FileSync = require('lowdb/adapters/FileSync');
const shortid = require('shortid');

const adapter = new FileSync('db.json');
const db = low(adapter);

module.exports = (app) => {

  app.get(`/api/users`, async (req, res) => {
    const users = db.get('users').value();
    return res.status(200).send(users);
  });

  app.post(`/api/user`, async (req, res) => {
    const { name, lastName } = req.body;
    const id = shortid.generate();
    const users = db
      .get('users')
      .push({ id, name, lastName })
      .write();

    const user = db.get('users')
      .find({ id })
      .value();

    return res.status(201).send({
      error: false,
      user
    });
  })

  app.put(`/api/user`, async (req, res) => {
    const { name, lastName, id } = req.body;

    let users = db.get('users')
        .find({ id })
        .assign({ name, lastName })
        .write();

    const user = db.get('users')
      .find({ id })
      .value();

    return res.status(202).send({
      error: false,
      user
    });
  });

  app.delete(`/api/user/:id`, async (req, res) => {
    const { id } = req.params;
    console.log(id);

    db.get('users')
      .remove({ id })
      .write()

    return res.status(202).send({
      error: false
    })

  })

}

```


Finally, open the index,js file, and after ``app.use(bodyParser.json())``, configure the api routes:


```javascript
require('./routes/userRoutes')(app);
```


Now we can run the backend using the url:http://localhost:5000/api/users and do get, insert, update e delete a user.

We can use [Postman](https://www.postman.com/) to add new users. Make a POST to http://localhost:5000/api/user with the json using this payload:
```javascript
{
  "name": "Bruno",
  "lastName": "Bezerra"
}
```

To facilitate the use of requests, just import the following [collecion](https://raw.githubusercontent.com/brunobc/node-react-project/master/users.postman_collection.json) in postman.


Now on the frontend (react) we will add a service in the /front/src/services folder called user.service.js to make requests.
```javascript
import axios from 'axios';

export default {
  getAll: async () => {
    let res = await axios.get(`/api/users`);
    return res.data || [];
  },
  add: async (name, lastName) => {
    let res = await axios.post(`/api/user/`, { name, lastName })
    return res.data || {};
  },
  edit: async (name, lastName, id) => {
    let res = await axios.put(`/api/user/`, { name, lastName, id })
    return res.data || {};
  },
  delete: async (id) => {
    let res = await axios.delete(`/api/user/${id}`);
    return res.data || [];   
  }
}
```

Edit the App.js to list users:
```javascript
import React, { useState, useEffect } from "react";

import userService from './services/user.service';

function App() {
  const [ users, setUsers ] = useState(null);

  useEffect(() => {
    if (!users) {
      getUsers();
    }
  })

  const getUsers = async () => {
    let res = await userService.getAll();
    setUsers(res);
  }

  const renderUser = user => {
    return (
      <li key={user._id} className="list__item user">
        <h3 className="user__name">{user.name}</h3>
        <h3 className="user__lastName">{user.lastName}</h3>
      </li>
    );
  };

  return (
    <div className="App">
      <ul className="list">
        {(users && users.length > 0) ? (
          users.map(user => renderUser(user))
        ) : (
          <p>No users found</p>
        )}
      </ul>
    </div>
  );
}

export default App;
```

And finally, we can run the command at the root of the project to run the backend and frontend:
```
npm run dev
```

![](https://raw.githubusercontent.com/brunobc/node-react-project/master/prints/listusers.png)

I hope this application is useful and serves as a starting point for future projects. :)
The source code can be found in [node-react-project](https://github.com/brunobc/node-react-project).