Membangun Rest API dengan Express dan Sequelize

Membangun Rest API dengan Express dan Sequelize

Program ADeveloper

·

7 min read

Pada kali ini kita akan menggunakan Sequelize sebagai ORM pada express js. ORM adalah singkatan dari Object Relation Model, dimana akan menjadikan data dari database dimapping menjadi object.

Persiapan dan instalasi

Sebelum berlanjut, periksa kembali apakah Nodejs dan MySQL telah terinstall di device masing-masing? Jika ya, mari kita lanjutlan.

Buatlah sebuah folder untuk menyimpan projek yang akan dikerjakan misal books, kemudian buka melalui terminal atau cmd, tuliskan perintah berikut.

npm init -y

Berdasarkan perintah tersebut didapatkan file package.json dan package-lock.json yang isi file package.json seperti berikut:

{
  "name": "books",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

Itu menandakan bahwa folder books telah ditandai sebagai project nodejs.

Selanjutnya, install dependensi yang dibutuhkan yakni express, cors, mysql2, dan sequelize dengan cara menjalankan perintah berikut pada terminal.

npm i --save express mysql2 cors sequelize

Jika telah tetambahkan pada package.json key dependencies yang isinya sesuai yang diinstallkan dan terdapat folder node_modules, maka proses install selesai.

{
  "name": "books",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.5",
    "express": "^4.17.3",
    "mysql2": "^2.3.3",
    "sequelize": "^6.17.0"
  }
}

Membuat server express

Tambahkan file server.js sebagai file utama yang menjalankan server yang isinya seperti berikut ini.

index.js

const express = require('express');
const cors = require('cors');
const app = express();
const port = 5000;

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

app.get('/', (req, res) => {
    res.send('Hello World!');
});


app.listen(port, () => console.log(`App listening on port http://localhost:${port}!`));

Lakukan uji dengan menjalankan server dengan perintah:

nodemon server.js

Jalankan pada browser atau pada postman, dengan url localhost:5000, Perhatikan gambar berikut. Server

Membuat model sequelize

Sebelum membuat model sequelize, perlu membuat file config untuk mendeklarasikan config dari database yang akan dipakai (dalam hal ini: mysql), jadi buatlah sebuah database misal namanya book_db, boleh menggunakan phpmyadmin atau pakai terminal.

mysql -u root -p

Masukkan password mysql server (sesuaikan dengan user dan password yang terpasang pada device masing-masing). Kemudian jalan perintah sql berikut untuk membuat database.

CREATE DATABASE book_db;

Sampai disitu saja tentang pembuatan database dari mysqlnya, kita lanjut dengan file config yang disimpan dalam folder app/config dengan nama db.config.js dan isinya seperti berikut ini.

db.config.js

module.exports = {
    HOST: 'localhost',
    USER: 'root',
    PASSWORD: '123456',
    DB: 'book_db',
    dialect: 'mysql',
    pool: {
        max: 5,
        min: 0,
        acquire: 30000,
        idle: 10000,
    },
}

Buatlah file model dengan nama book.model.js yang disimpan pada folder app/models dan isinya seperti berikut.

book.model.js

module.exports = (sequelize, Sequelize) => {
    const Book = sequelize.define('book', {
        title: {
            type: Sequelize.STRING,
        },
        description: {
            type: Sequelize.TEXT,
        },
        published: {
            type: Sequelize.BOOLEAN,
        },
    });
    return Book;
}

Tidak cukup sampai disitu, buatlah file yang akan menjalankan semua model yang ada pada projet dengan nama file index.js yang disimpan pada folder app\models yang isinya seperti berikut.

index.js

const dbConfig = require('../config/db.config');
const Sequelize = require('sequelize');
const sequelize = new Sequelize(
    dbConfig.DB, 
    dbConfig.USER, 
    dbConfig.PASSWORD, {
        host: dbConfig.HOST,
        dialect: dbConfig.dialect,
        operatorAlias: false,
        pool: {
            max: dbConfig.pool.max,
            min: dbConfig.pool.min,
            acquire: dbConfig.pool.acquire,
            idle: dbConfig.pool.idle
        },
    });
const db = {};
db.Sequelize = Sequelize;
db.sequelize = sequelize;

// define semua models yang ada pada aplikasi
db.books = require('./book.model')(sequelize, Sequelize);
module.exports = db;

Lalu berikut daftar tipe data yang sering dipakai pada sequelize dengan mysql.

Sequelize.STRING                      // VARCHAR(255)
Sequelize.STRING(1234)                // VARCHAR(1234)
Sequelize.STRING.BINARY               // VARCHAR BINARY
Sequelize.TEXT                        // TEXT
Sequelize.TEXT('tiny')                // TINYTEXT
Sequelize.INTEGER                     // INTEGER
Sequelize.BIGINT                      // BIGINT
Sequelize.BIGINT(11)                  // BIGINT(11)
Sequelize.FLOAT                       // FLOAT
Sequelize.FLOAT(11)                   // FLOAT(11)
Sequelize.FLOAT(11, 10)               // FLOAT(11,10)
Sequelize.DOUBLE                      // DOUBLE
Sequelize.DOUBLE(11)                  // DOUBLE(11)
Sequelize.DOUBLE(11, 10)              // DOUBLE(11,10)
Sequelize.DECIMAL                     // DECIMAL
Sequelize.DECIMAL(10, 2)              // DECIMAL(10,2)
Sequelize.DATEONLY                    // DATE without time.
Sequelize.BOOLEAN                     // TINYINT(1)
Sequelize.ENUM('value 1', 'value 2')  
Sequelize.JSON                        // JSON

Controller dan penggunaan model untuk CRUD

Controller adalah file yang bertugas melakukan eksekusi logic terhadap request dari user yang dijalankan bisajadi melibatkan model untuk dijadikan response ke user. Caranya buatlah file book.controller.js yang disimpan dalam folder app/controllers yang isinya seperti berikut.

book.controller.js

const db = require("../models");
const Book = db.books;

// CREATE: untuk enambahkan data kedalam tabel book
exports.create = (req, res) => {
  // validate request
  if (!req.body.title) {
    return res.status(400).send({
      message: "Title can not be empty",
    });
  }

  // daya yang didapatkan dari inputan oleh pengguna
  const book = {
    title: req.body.title,
    description: req.body.description,
    published: req.body.published ? req.body.published : false,
  };

  // proses menyimpan kedalam database
  Book.create(book)
    .then((data) => {
      res.json({
        message: "Book created successfully.",
        data: data,
      });
    })
    .catch((err) => {
      res.status(500).json({
        message: err.message || "Some error occurred while creating the Book.",
        data: null,
      });
    });
};

// READ: menampilkan atau mengambil semua data sesuai model dari database
exports.findAll = (req, res) => {
  Book.findAll()
    .then((books) => {
      res.json({
        message: "Books retrieved successfully.",
        data: books,
      });
    })
    .catch((err) => {
      res.status(500).json({
        message: err.message || "Some error occurred while retrieving books.",
        data: null,
      });
    });
};

// UPDATE: Merubah data sesuai dengan id yang dikirimkan sebagai params 
exports.update = (req, res) => {
  const id = req.params.id;
  Book.update(req.body, {
    where: { id },
  })
    .then((num) => {
      if (num == 1) {
        res.json({
          message: "Book updated successfully.",
          data: req.body,
        });
      } else {
        res.json({
          message: `Cannot update book with id=${id}. Maybe book was not found or req.body is empty!`,
          data: req.body,
        });
      }
    })
    .catch((err) => {
      res.status(500).json({
        message: err.message || "Some error occurred while updating the book.",
        data: null,
      });
    });
};

// DELETE: Menghapus data sesuai id yang dikirimkan
exports.delete = (req, res) => {
  const id = req.params.id;
  Book.destroy({
    where: { id },
  })
    .then((num) => {
      if (num == 1) {
        res.json({
          message: "Book deleted successfully.",
          data: req.body,
        });
      } else {
        res.json({
          message: `Cannot delete book with id=${id}. Maybe book was not found!`,
          data: req.body,
        });
      }
    })
    .catch((err) => {
      res.status(500).json({
        message: err.message || "Some error occurred while deleting the book.",
        data: null,
      });
    });
};

// BONUS ===> Mengambil data sesuai id yang dikirimkan
exports.findOne = (req, res) => {
  Book.findByPk(req.params.id)
    .then((book) => {
      res.json({
        message: "Book retrieved successfully.",
        data: book,
      });
    })
    .catch((err) => {
      res.status(500).json({
        message: err.message || "Some error occurred while retrieving book.",
        data: null,
      });
    });
};

Berdasarkan controller yang telah dibuat, maka sekarang kita telah mempunyai function yang dapat menambah, membaca, update dan hapus data kedalam database. Lalu sekarang kita butuh menyambungkannya ke router sesuai dengan fungsinya masing-masing.

Route Rest API

Route ini adalah yang mengatur permintaan user diproses oleh contoller yang mana. Misalnya pada aplikasi rest api book ini saya gambarkan seperti berikut.

Menambahkan data
HTTP Method: POST
Route: `/api/books`
Body:
{
    "title": "30 hari javascript",
    "description": "Mempelajari lebih dalam javascript selama 30 hari",
    "published": false
}
Membaca semua data
HTTP Method: GET
Route: `/api/books`
Mengubah data
HTTP Method: PUT
Route: `/api/books/:id`
Body:
{
    "title": "30 hari javascript",
    "description": "Mempelajari lebih dalam javascript selama 30 hari",
    "published": false
}
Menghapus data
HTTP Method: DELETE
Route: `/api/books/:id`
Mengambil data sesuai id
HTTP Method: GET
Route: `/api/books/:id`

Berdasarkan data tersebut, maka buatlah file router dengan nama book.routes.js yang disimpan pada folder app\routes dan isinya seperti berikut ini.

book.routes.js

const bookController = require('../controllers/book.controller');
const router = require('express').Router();

router.post('/', bookController.create);
router.get('/', bookController.findAll);
router.put('/:id', bookController.update);
router.put('/:id', bookController.update);
router.delete('/:id', bookController.delete);
router.get('/:id', bookController.findOne);

module.exports = router;

Finishing

Agar apliasinya dapat berjalan maka models, controller, dan router yang telah dibuat dihubungkan pada file server.js yang telah ada sebelumnya dengan melakukan perubahan sehingga menjadi seperti berikut.

server.js

const express = require('express');
const cors = require('cors');
const app = express();
const port = 5000;
const bookRoute = require('./app/routes/book.routes');

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

const db = require('./app/models');
db.sequelize.sync();

app.get('/', (req, res) => {
    res.send('Hello World!');
});

app.use('/api/books', bookRoute);

app.listen(port, () => console.log(`App listening on port http://localhost:${port}!`));

Uji dengan HTTP Client

Melakukan uji apakah rest api telah berjalan dengan baik, bisa menggunakan aplikasi Http client misal: Postman, Insomnia, Thunderclient, CURL, dll.

Jalankan server dengan nodemon server.js, maka akan terlihat pembuatan tabel sesuai model yang didefine seperti gambar berikut. Server

CREATE CREATE

READ READ

UPDATE UPDATE

DELETE DELETE

GET BY ID CREATE

Itu saja materi kali ini, untuk melihat video dan source materi dapat saya alihkan ke: