Customer: Use Case (2: Implementing ExpressJS Service)
Published: 2023-11-29 05:39:47

## Prerequisites
1. Installed Node version of `v20.10.0`
2. Installed PostgreSQL version of `16`
3. Database viewer, I use DBeaver

## Creating customer table
1. Open DBeaver application
2. Click `Database` then choose `New Database Connection` assuming you haven't connect to PostgreSQL database.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hcuu0fe2c9g0omyvynym.png)
3. Choose `PostgreSQL`. Then click `Next`.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bgzdja4u3r9x3ts29og1.png)
4. I'm using the default connection settings so just click `Finish`.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i3opnxxqt46vjdwr5d3i.png)
5. You will see the newly connected PostgreSQL on the left side navigator.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z2ywklz4oljzcd1f8388.png)
6. Click the dropdown arrow until you can see this:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c5wf4rxtgukd22k9u7hc.png)
7. Click right at `Databases`. Choose `Create New Database`.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xofzsdavlg7ncxysguj.png)
8. Fill the database name field with `customer`. Then click OK.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2yftdaurzli3z5l5uzfp.png)
9. Click on database dropdown and now you will see your new database.
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nnyheob9fgfwvivabtg.png)
If you did not see your new database, please follow [this step](https://stackoverflow.com/a/60289190).

## Initialize express application
I'm assuming that you have already created project directories just like what I did in the first post.
1. Open a `command prompt` from express-service root directory.
2. Init a npm project by using command of:
    ```
    npm init
    ```
3. Install these dependencies:
    ####Basic dependencies
        ```
        npm install express dotenv cors body-parser
        ```
    ####Sequalize dependency
        ```
        npm install sequelize
        ```
    ####PostgreSQL dependency
        ```
        npm install pg pg-hstore
        ```
    ####UUID dependency
        ```
        npm install uuid
        ```
    My package.json dependencies looks like:
    ```
    "dependencies": {
        "body-parser": "^1.20.2",
        "cors": "^2.8.5",
        "dotenv": "^16.3.1",
        "express": "^4.18.2",
        "pg": "^8.11.3",
        "pg-hstore": "^2.3.4",
        "sequelize": "^6.35.1",
        "uuid": "^9.0.1"
      }
    ```
4. Create project directory skeleton that looks like this:
    ```
    express-service/
        ├── src/
        │   ├── configs/
        │   ├── controllers/
        │   ├── models/
        │   └── routes/
        ├── .env
        ├── index.js
        ├── package.json
        └── server.js
    ```

5. My `.env` file looks like below. Makesure that you have correct and working port and credentials.
    ```
    PORT=3001
    DB_HOST=localhost
    DB_PORT=5432
    DB_USERNAME=postgres
    DB_PASSWORD=password
    DB_NAME=customer
    ```

## Creating configs
Inside `configs` directory, create a file named `db.config.js` the content will look like this:
```
require('dotenv').config();

module.exports = {
  HOST: process.env.DB_HOST,
  USER: process.env.DB_USERNAME,
  PASSWORD: process.env.DB_PASSWORD,
  DB: process.env.DB_NAME,
  dialect: "postgres",
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
};
```
This is the configuration to connect our application to the database.

## creating models
Now, let's move on to out `models` directory
1. Create a file called `customer.model.js`.
    ```
    module.exports = (sequalize, Sequalize) => {
      const Customer = sequalize.define("customer", {
        no: {
          type: Sequalize.UUID
        }, 
        nama: {
          type: Sequalize.STRING
        },
        alamat: {
          type: Sequalize.STRING
        },
        kota: {
          type: Sequalize.STRING
        }
      });
    
      return Customer;
    };
    ```
2. Create another file called `index.js`.
    ```
    const dbConfig = require("../configs/db.config");
    
    const Sequalize = require("sequelize");
    const sequalize = new Sequalize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, {
      host: dbConfig.HOST,
      dialect: 'postgres',
      operatorAliases: false,
    
      pool: {
        max: dbConfig.pool.max,
        min: dbConfig.pool.min,
        acquire: dbConfig.pool.acquire,
        idle: dbConfig.pool.idle
      }
    });
    
    const db = {};
    
    db.Sequalize = Sequalize;
    db.sequalize = sequalize;
    
    db.customer = require("./customer.model")(sequalize, Sequalize);
    
    module.exports = db;
    ```

## Creating controllers
After configuring our model let's create the controller for customer by making a file called `customer.controller.js`.
```
const { v4: uuidv4 } = require('uuid');
const db = require("../models");
const model = require("../models");
const Customer = model.customer;
const Op = db.Sequalize.Op;

exports.create = (req, res) => {

  const customer = {
    no: uuidv4(),
    nama: req.body.nama,
    alamat: req.body.alamat,
    kota: req.body.kota
  };

  Customer.create(customer)
    .then((data) => {
      res.send(data);
    }).catch((err) => {
      res.status(500).send({
        message:
          err.message || "Some error occurred while creating the Customer."
      });
    });

};

exports.findAll = (req, res) => {

  Customer.findAll()
    .then((data) => {
      res.send(data);
    }).catch((err) => {
      res.status(500).send({
        message:
          err.message || "Some error occurred while retrieving the Customer."
      });
    });

};

exports.findOne = (req, res) => {

  const id = req.params.id;

  Customer.findByPk(id)
    .then((data) => {
      res.send(data);
    }).catch((err) => {
      res.status(400).send({
        message:
          "Error retrieving Customer with id=" + id
      });
    });

};

exports.update = (req, res) => {

  const id = req.params.id;

  Customer.update(req.body, { where: { id: id } })
    .then((data) => {
      if (data[0] === 1) {
        res.send("Successfully updated Customer with id " + id);
      } else {
        res.send("Cannot update Customer with id " + id);
      }
    }).catch((err) => {
      res.status(500).send({
        message: "Error updating Customer with id=" + id
      });
    });

};

exports.delete = (req, res) => {

  const id = req.params.id;

  Customer.destroy({ where: { id: id } })
    .then((data) => {
      if (data === 1) {
        res.send("Successfully deleted Customer with id " + id);
      } else {
        res.send("Cannot delete Customer with id " + id);
      }
    }).catch((err) => {
      res.status(500).send({
        message: "Error deleting Customer with id=" + id
      });
    });

};

```
## Creating routes
Last, we need to create our route in `customer.route.js` inside `route` directory.
```
module.exports = app => {
  const customers = require("../controllers/customer.controller");

  var router = require("express").Router();

  router.post("/", customers.create);

  router.get("/", customers.findAll);

  router.get("/:id", customers.findOne);

  router.put("/:id", customers.update);

  router.delete("/:id", customers.delete);

  app.use('/api/customers', router);
};
```
## Configuring server
In `server.js` file which located in root directory, we will configuring all needed dependency and connect our application to database like this:
```
const express = require("express");
const bodyParser = require("body-parser");
const cors = require("cors");

require('dotenv').config();

function startServer() {
  const app = express();

  app.use(cors());

  app.use(express.json());

  app.use(express.urlencoded({ extended: true }));

  const db = require("./src/models");

  db.sequalize.sync()
    .then(() => {
      console.log("Synced db.");
    }).catch((err) => {
      console.log("Failed to sync db: " + err.message);
    });
  
    require("./src/routes/customer.routes")(app);

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

module.exports = { start: startServer };
```
## Configure index.js
Since most functionalities all already handled by `server.js`, in `index.js` we just have to call it like this:
```
const server = require('./server');

server.start();
```
## Running application
1. Back to `express-service` root directory, open command prompt directed to the directory.
2. Run `node index.js`
3. If it running correctly you will see this log:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bcktsoiyf4modfc8uj6g.png)
4. Test your API endpoints using Postman or Thunder Client.