Pengenalan Awal
Hei hei…. apa kabar nih kalian? Moga tetep sehat meski masih masa pandemi gini ya. Berhubung aku lagi nyoba belajar javascript jadi kali ini aku pengen share ama kalian gimana sih caranya bikin RestAPI dengan nodejs dan mysql. Btw kalian udah tau belum RestAPI itu apaan?
Yah kalo aku artikan secara simple sih RestAPI itu bisa kita bayangkan sebagai semacam perantara antara server dengan client. Jadi saat client melakukan request maka server akan memberikan response (kalau kalian ada pendapat lain bisa share di kolom komentar ya). Ok biar ga lama yuk lanjut ke materi.
untuk source code bisa dilihat di https://github.com/atrem13/medium/tree/master/nodejs-mysql-restApi-try1 :)oh iya aku juga nulis beberapa materi di medium jadi kalau tertarik bisa mampir ke https://medium.com/@atrem13
Struktur folder kalian nanti bakal kayak gini
RestAPI yang akan kita buat nanti akan memungkinkan client untuk melakukan Create, Read, Update, Delete(CRUD) suatu data pada tabel pelanggan. Karena kita bakal pake npm jadi aku minta kalian udah pada install node di laptop/komputer masing masing (yang belum bisa install dulu, cek di https://nodejs.org/en/ ).
Kalau udah, demi mempermudah kerja kalian silahkan install juga express generator melalui npm dengan cara dengan menjalankan perintah berikut
npm install -g express-generator
perintah diatas akan menginstall express-generator secara global di laptop/komputer kalian ( untuk lengkapnya bisa cek lagi disini https://expressjs.com/en/starter/generator.html )
sekarang kita bakal buat project RestAPI dengan express generator, silahkan jalankan perintah berikut:
express nodejs-mysql-restApi-try1 –-no-view
Perintah diatas akan membuatkan folder baru dengan nama nodejs-mysql-restApi-try1(aku emang kebiasaan ngasi nama detail gini biar tau projek apa ini, kalau kalian mau pakai nama lain boleh aja), silahkan masuk direktori nodejs-mysql-restApi-try1 yang baru saja dibuat lalu jalankan
npm install
Ok selanjutnya karena kita akan menggunakan mysql untuk databse dan cors agar bisa mendapat data request dari client jadi kita install dulu mysql dan cors dengan cara menjalankan perintah
npm install mysql cors –-save
perlu kalian ketahui saat kalian menjalankan app nodejs, jika kalian melakukan perubahan pada file maka kalian harus me-restart server.
Untuk melakukannya secara otomatis silahkan install nodemon dengan cara menjalankan perintah:
npm install nodemon –-save-dev
kalau udah harusnya tampilan folder dan file package.json kalian bakal kayak gini
dan tampilan app.js kalian kayak gini
Sekarang siapkan database untuk kita gunakan, nama databasenya adalah testDB, di database ini kita tambahkan tabel customers dengan format seperti ini:
CREATE TABLE IF NOT EXISTS `customers` (
id INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(255) NOT NULL,
NAME VARCHAR(255) NOT NULL,
active BOOLEAN DEFAULT FALSE
) ENGINE=INNODB DEFAULT CHARSET=utf8;
Karena database sudah siap ayo kita buat folder baru dengan nama config didalam folder config itu kita buat sebuah file dengan nama db.config.js file ini akan berisi data konfigurasi database kita
Tambahkan kode berikut ke file db.config.js
module.exports = {
HOST: "localhost",
USER: "root", //biasanya root
PASSWORD: "password", //kalau ada diisi, kalau tidak isi dengan ""
DB: "testDB"
};
// kita mengexport 4 variable yang berisi data untuk penggunaan database
Selanjutnya kembali ke root folder dan tambahkan folder models, di folder models tambahkan sebuah file dengan nama db.js Pada file db.js kita akan menghubungkan projek kita dengan database. Tambahkan kode berikut di file models\db.js
// include mysql yang telah diinstall
const mysql = require("mysql");
// include data untuk konfigurasi database
const dbConfig = require("../config/db.config.js");
// membuat koneksi ke database
const connection = mysql.createConnection({
host: dbConfig.HOST,
user: dbConfig.USER,
password: dbConfig.PASSWORD,
database: dbConfig.DB
});
// melakukan koneksi dan mengecek apakah terjadi error atau tidak
connection.connect(error => {
if (error) throw error;
console.log("Successfully connected to the database.");
});
module.exports = connection;
Karena kita akan melakukan CRUD pada data tabel customers maka kita siapkan terlebih dahulu model dari tabel customers.
Pada folder models tambahkan file dengan nama customer.model.js, fungsi dari file ini adalah untuk mendefinisikan struktur dari tabel customers yang sudah kita buat tadi, dengan file ini juga kita dapat melakukan crud dengan menambahkan beberapa fungsi.
Untuk itu tambahkan kode berikut pada file models\customer.model.js
// kita include file db.js yang berisi koneksi ke database kita
const sql = require("./db.js");
// constructor
// berfungsi untuk mendifinisikan table customer itu memiliki column apa saja untuk diisi
const Customer = function(customer) {
this.email = customer.email;
this.name = customer.name;
this.active = customer.active;
};
// selain mendefinisikan column dari tabel customer, kita juga tambahkan fungsi untuk melakukan CRUD terhadap tabel customers
// fungsi untuk menambah data custumer baru
Customer.create = (newCustomer, result) => {
sql.query("INSERT INTO customers SET ?", newCustomer, (err, res) => {
// cek apakah terjadi error saat menambahkan data
if (err) {
// kalau error akan memberikan response error apa yang terjadi
console.log("error: ", err);
result(err, null);
return;
}
// jika tidak ada error akan memberikan response data yang berhasil dimasukan
console.log("created customer: ", { id: res.insertId, ...newCustomer });
result(null, { id: res.insertId, ...newCustomer });
});
};
// fungsi untuk mengambil data customer berdasarkan id
Customer.findById = (customerId, result) => {
sql.query(`SELECT * FROM customers WHERE id = ${customerId}`, (err, res) => {
// cek apakah terjadi error saat menambahkan data
if (err) {
// kalau error akan memberikan response error apa yang terjadi
console.log("error: ", err);
result(err, null);
return;
}
// kalau ada data yang berhasil diupdate maka akan memberi response data yang dicari berdasarkan id
if (res.length) {
console.log("found customer: ", res[0]);
result(null, res[0]);
return;
}
// kalau tidak menemukan data customer dengan id yang dimaksud maka akan diberi response pemberitahuan data tidak ditemukan
result({ kind: "not_found" }, null);
});
};
// fungsi untuk mengambil data dari semua customer
Customer.getAll = result => {
sql.query("SELECT * FROM customers", (err, res) => {
// cek apakah terjadi error saat menambahkan data
if (err) {
// kalau error akan memberikan response error apa yang terjadi
console.log("error: ", err);
result(null, err);
return;
}
// kalau tidak ada error akan memberi response list data customer yang ada
console.log("customers: ", res);
result(null, res);
});
};
// fungsi untuk mengupdate data customer berdasarkan id
Customer.updateById = (id, customer, result) => {
sql.query(
"UPDATE customers SET email = ?, name = ?, active = ? WHERE id = ?",
[customer.email, customer.name, customer.active, id],
(err, res) => {
// cek apakah terjadi error saat menambahkan data
if (err) {
// kalau error akan memberikan response error apa yang terjadi
console.log("error: ", err);
result(null, err);
return;
}
// cek apakah tidak ada data yang terupdate
if (res.affectedRows == 0) {
// akan memberikan response pemberitahuan bahwa data dengan id yang dimaksud tidak ada
result({ kind: "not_found" }, null);
return;
}
// kalau tidak ada error maka akan memberi response dari data yang baru diupdate
console.log("updated customer: ", { id: id, ...customer });
result(null, { id: id, ...customer });
}
);
};
// fungsi untuk menghapus customer dari tabel berdasarkan id
Customer.remove = (id, result) => {
sql.query("DELETE FROM customers WHERE id = ?", id, (err, res) => {
// cek apakah terjadi error saat menambahkan data
if (err) {
// kalau error akan memberikan response error apa yang terjadi
console.log("error: ", err);
result(null, err);
return;
}
// cek apakah tidak ada data yang terhapus
if (res.affectedRows == 0) {
// akan memberikan response pemberitahuan bahwa data dengan id yang dimaksud tidak ada
result({ kind: "not_found" }, null);
return;
}
// kalau tidak ada error maka akan memberi response pemberitahuan id data yang baru dihapus
console.log("deleted customer with id: ", id);
result(null, res);
});
};
// terakhir kita exports model Customer yang berisi struktur tabel dan semua fungsi diatas untuk melakukan crud customers
module.exports = Customer;
Penjelasan kode diatas sudah aku jelasin pake komentar, jadi kalian bisa baca baca dan kalau bingung bisa tanyain di kolom komentar v:
Nah karena model udah siap sekarang waktunya tambahin controller, apaan lagi sih controller mer? Sederhananya dengan controller kita bisa atur apa yang akan dilakukan ketika client melakukan request/mengakses route tertentu (kita bakal buat route juga nanti kok). Bayangin aja ketika client melakukan request untuk menambahkan data baru ke table customers, maka controller akan memberi tahu server untuk menjalankan fungsi create yang ada pada file customer.model.js
sekarang balik dulu ke root folder terus tambahin folder dengan nama controllers, di folder controllers tambahin satu file dengan nama customer.controller.js, fungsi dari file ini adalah untuk memanggil / menjalankan fungsi yang udah kalian buat di file models\customer.model.js tadi.
Tambahin kode berikut di file controllers\customer.controller.js
// kita include dulu file models/customer.model.js biar nanti kita bisa panggil fungsi dari file ini di controller
const Customer = require("../models/customer.model.js");
// menambahkan data customer baru
exports.create = (req, res) => {
// validasi input
if (!req.body) {
// mengirimkan response error jika input kosong
res.status(400).send({
message: "Content can not be empty!"
});
}
// inisialisasi data untuk customer baru
const customer = new Customer({
email: req.body.email,
name: req.body.name,
active: req.body.active
});
// menyimppan data customerbaru di database
// bisa kalian perhatikan disini kita memanggil fungsi crerate pada file models/customer.model.js dan mengirim parameter kesana
Customer.create(customer, (err, data) => {
// cek apakah terjadi error atau tidak
if (err)
// mengirim response error jika terjadi error
res.status(500).send({
message:
err.message || "Some error occurred while creating the Customer."
});
// kalau tidak ada error maka akan mengirim response data yang baru saja dimasukan ke database
else res.send(data);
});
};
// mengambil data semua customer dari database
exports.findAll = (req, res) => {
// bisa kalian perhatikan disini kita memanggil fungsi getAll pada file models/customer.model.js dan mengirim parameter kesana
Customer.getAll((err, data) => {
// cek apakah terjadi error atau tidak
if (err)
// mengirim response error jika terjadi error
res.status(500).send({
message:
err.message || "Some error occurred while retrieving customers."
});
// kalau tidak ada error maka akan mengirim response data semua customer pada database
else res.send(data);
});
};
// mengambil data seorang customer berdasarkan id
exports.findOne = (req, res) => {
// bisa kalian perhatikan disini kita memanggil fungsi findById pada file models/customer.model.js dan mengirim parameter kesana
Customer.findById(req.params.customerId, (err, data) => {
// cek apakah terjadi error atau tidak
if (err) {
// disini kita cek error apa yang terjadi
// cek apakah data dengan id yang dimaksud ada atau tidak. (aku yakin kalian yang baru belajar jadi agak bingung disini. coba baca ulang fungsi findById di file models/customer.model.js lalu pahami bagaimana dia berinteraksi disini)
if (err.kind === "not_found") {
// mengirim response error id yang dimaksud tidak ada
res.status(404).send({
message: `Not found Customer with id ${req.params.customerId}.`
});
} else {
// mengirim response error jika terjadi error selain error id tidak ditemukan
res.status(500).send({
message: "Error retrieving Customer with id " + req.params.customerId
});
}
} else {
// kalau tidak ada error maka akan memberi response data dari customer dengan id yang dimaksud
res.send(data);
}
});
};
// update customer berdasarkan id
exports.update = (req, res) => {
// validasi input
if (!req.body) {
// mengirim response error input kosong
res.status(400).send({
message: "Content can not be empty!"
});
}
// bisa kalian perhatikan disini kita memanggil fungsi updateById pada file models/customer.model.js dan mengirim parameter kesana
Customer.updateById(req.params.customerId, new Customer(req.body),
(err, data) => {
// cek apakah terjadi error
if (err) {
// cek jenis error
if (err.kind === "not_found") {
// mengirim response error id yang dimaksud tidak ada
res.status(404).send({
message: `Not found Customer with id ${req.params.customerId}.`
});
} else {
// mengirim response error selain error id tidak ditemukan
res.status(500).send({
message: "Error updating Customer with id " + req.params.customerId
});
}
} else {
// kalau tidak ada error maka akan memberi response data hasil update dari customer dengan id yang dimaksud
res.send(data);
}
}
);
};
// delete customer berdasarkan id
exports.delete = (req, res) => {
// bisa kalian perhatikan disini kita memanggil fungsi remove pada file models/customer.model.js dan mengirim parameter kesana
Customer.remove(req.params.customerId, (err, data) => {
// cek apakah terjadi error
if (err) {
// cek jenis error
if (err.kind === "not_found") {
// mengirim response error id yang dimaksud tidak ada
res.status(404).send({
message: `Not found Customer with id ${req.params.customerId}.`
});
} else {
// mengirim response error selain error id tidak ditemukan
res.status(500).send({
message: "Could not delete Customer with id " + req.params.customerId
});
}
} else {
// mengirim response pemberitahuan data berhasil customer dengan id yang dimaksud berhasil dihapus
res.send({ message: `Customer was deleted successfully!` });
}
});
};
// bisa kalian perhatikan semua fungsi diatas langsung kita export
Terakhir kita bakal buat file customer.route.js pada folder routes, sebelumnya kalian bisa kosongin folder routes terlebih dahulu karena kita ga perlu file itu (kalau ga salah ada file index dan user di folder routes, itu hapus aja ya).
Selanjutnya pada file routes\customer.route.js tambahin kode berikut:
// disini kita akan mengeksport route berikut
module.exports = app => {
// include file customer.controller.js agar kita bisa meminta server menjalankan fungsi dari file ini ketika client mengakses route / melakukan request tertentu
const customers = require("../controllers/customer.controller.js");
// saat client mengakses route /customers dengan method post maka server akan memanggil fungsi create pada file customer.controller.js. dimana controller akan menjalankan fungsi untuk menambahkan data baru ke tabel customers pada database
app.post("/customers", customers.create);
// saat client mengakses route /customers dengan method get maka server akan memanggil fungsi findAll pada file customer.controller.js. dimana controller akan menjalankan fungsi untuk mengambil/menampilkan seluruh data customer pada database
app.get("/customers", customers.findAll);
// saat client mengakses route /customers/:customerId(:customerId merupakan parameter route) dengan method get maka server akan memanggil fungsi findOne pada file customer.controller.js dimana fungsi ini akan mengambil/menampilkan data customer pada database berdasarkan id (id ditentukan dengan parameter yang diberikan, misal /customers/2 artinya memberikan parameter '2' kemudian mencari data customer dengan id 2)
app.get("/customers/:customerId", customers.findOne);
// saat client mengakses route /customers/:customerId(:customerId merupakan parameter route) dengan method put maka server akan memanggil fungsi update pada file customer.controller.js dimana fungsi ini akan mengupdate data customer pada database berdasarkan id
app.put("/customers/:customerId", customers.update);
// saat client mengakses route /customers/:customerId(:customerId merupakan parameter route) dengan method delete maka server akan memanggil fungsi delete pada file customer.controller.js dimana fungsi ini akan mengupdate data customer pada database berdasarkan id
app.delete("/customers/:customerId", customers.delete);
};
Sama seperti sebelumnya penjelasan kode bisa dibaca sendiri, aku udah tambahin komentar di kode diatas ( jujur code nya dikit tapi komentarnya kebanyakan wkwkwkwk v: )
Sekarang kita hubungin dulu app kita dengan route yang udah kita buat, balik ke root folder terus edit file app.js jadi seperti berikut:
const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const cors = require('cors');
const app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// disini kita kasi tau server untuk menggunakan route yang tadi kita buat di file routes/customer.route
require('./routes/customer.route')(app);
module.exports = app;
pada kode diatas kita include file customer.route.js yang kita udah buat ke file app.js
Waktunya testing RestAPI yang udah kita, kita bakal test menggunakan postman (kalau belum punya bisa install dulu di https://www.postman.com/)
Pertama kembali ke root folder dan jalankan perintah berikut untuk menjalankan server
Nodemon
Kalau berhasil maka akan muncul seperti ini
Kalo udah yuk test dulu di postman
Pertama kita cek untuk insert data baru
Ok berhasil masuk ya, aku bakal coba masukin beberapa data lagi biar lebih enak diliat
Selanjutnya di test berikutnya kita bakal cek untuk dapetin semua data customer (saat ini ada 3 data customer di database)
Ok berhasil juga
Selanjutnya cek get data berdasarkan id, kita coba dapetin data dari customer dengan id 2
sip berhasil juga
Selanjutnya coba update data customer dengan id 2
ok berhasil juga bisa cek juga apa udah ke update di database atau belum
Terakhir kita hapus data customer dengan id 1
sip berhasil
Akhirnya kelar juga seri kali ini, kalau kalian udah langsung paham artinya kalian hebat banget, karena aku pribadi perlu sekitar seminggu lebih buat paham materi ini wkwkwk, tapi kalau kalian masih kurang paham wajar aja karena baru nyoba dan mungkin aku juga kurang bagus jelasinnya, jadi jangan patah semangat ya.
Sekali lagi untuk source code bisa dilihat di https://github.com/atrem13/medium/tree/master/nodejs-mysql-restApi-try1
dan untuk materi lainnya bisa cek di medium ku di https://medium.com/@atrem13
Seperti biasa ini Cuma basic, masih banyak yang bisa kalian explore diluar sana. Kalau ada yang punya pendapat lain atau mungkin kurang setuju ama yang aku tulis bisa kita diskusi di kolom komentar ya. Seperti biasa kalau ada salah kata atau sejenisnya mohon dimaafkan dan kalau bisa dikoreksi agar aku bisa lebih baik lagi kedepannya.
Oke itu dulu untuk seri kali ini, saya Merta pamit undur diri dan ingat untuk ‘Haus akan ilmu baru’