Cara Membangun Aplikasi CRUD dengan Node.js
Node.js adalah lingkungan runtime JavaScript yang berjalan di sisi server dan sering dimanfaatkan untuk membangun berbagai jenis aplikasi web, termasuk aplikasi CRUD (Create, Read, Update, Delete). CRUD adalah istilah yang menggambarkan empat operasi dasar pada data: penambahan, pembacaan, pembaruan, dan penghapusan. Dalam artikel ini, kita akan membahas cara membangun aplikasi CRUD menggunakan Node.js, lengkap dengan Express sebagai framework HTTP dan contoh penggunaan database.
1. Persiapan Dasar
1.1. Instalasi Node.js
Sebelum memulai, pastikan Node.js telah terpasang di komputer. Untuk memverifikasi, buka terminal dan ketik:
node -v
Jika Node.js belum terpasang, silakan unduh installer dari Node.js dan ikuti petunjuk pemasangannya.
1.2. Membuat Folder Proyek
Setelah Node.js siap, buat direktori proyek baru:
mkdir crud-app
cd crud-app
Kemudian inisialisasi package.json:
npm init -y
File package.json
akan dihasilkan secara otomatis dengan konfigurasi default.
1.3. Instalasi Dependensi
Kita akan menggunakan beberapa dependensi dasar:
- Express: Untuk mempermudah pembuatan server HTTP dan manajemen routing.
- cors (opsional): Untuk menangani kebijakan Cross-Origin Resource Sharing jika ingin diakses dari domain berbeda.
- body-parser (atau fitur bawaan Express) untuk memproses request body.
- dotenv: Agar dapat menyimpan variabel sensitif (seperti kredensial database) di file
.env
. - Driver database (misalnya
mysql2
untuk MySQL ataumongoose
untuk MongoDB) tergantung pilihanmu.
Sebagai contoh, kita akan menggunakan MySQL. Install semuanya:
npm install express cors mysql2 dotenv
Apabila lebih menyukai MongoDB, silakan ganti mysql2
dengan mongoose
, lalu menyesuaikan script.
2. Struktur Proyek
Untuk kemudahan pengembangan, kita akan menata struktur direktori secara modular. Berikut contoh strukturnya:
crud-app/
├─ config/
│ └─ db.js
├─ controllers/
│ └─ userController.js
├─ models/
│ └─ userModel.js (opsional, jika ingin pakai ORM/structured approach)
├─ routes/
│ └─ userRoutes.js
├─ .env
├─ app.js
├─ package.json
└─ package-lock.json
Penjelasan singkat:
config/
berisi file konfigurasi, seperti koneksi ke database.controllers/
menyimpan logika untuk setiap endpoint (Create, Read, Update, Delete).models/
bisa berisi definisi model data jika menggunakan ORM atau sekadar menampung query yang berkaitan dengan data (optional).routes/
mengelompokkan endpoint yang berhubungan dengan entity tertentu, misalnyauserRoutes.js
untuk semua operasi terkait user.app.js
akan menjadi titik masuk (entry point) untuk menjalankan server.
3. Koneksi Database (MySQL)
3.1. Menyiapkan Database
Pertama-tama, pastikan MySQL sudah terpasang. Buka MySQL CLI atau MySQL Workbench, lalu buat database baru:
CREATE DATABASE crud_db;
USE crud_db;
Buat tabel sederhana, misalnya untuk menyimpan data pengguna:
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
email VARCHAR(50) NOT NULL,
age INT
);
Struktur di atas akan menampung data dengan kolom name
, email
, dan age
.
3.2. File Konfigurasi .env
Untuk menyimpan kredensial database, kita buat file .env
di root folder:
DB_HOST=localhost
DB_USER=root
DB_PASS=your_password
DB_NAME=crud_db
DB_PORT=3306
Pastikan file .env
dimasukkan ke .gitignore
agar tidak tersimpan ke repositori publik.
3.3. Membuat db.js
di Folder config
Buatlah file config/db.js
untuk mengelola koneksi MySQL:
require('dotenv').config();
const mysql = require('mysql2');
// Membuat pool koneksi
const pool = mysql.createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
port: process.env.DB_PORT,
connectionLimit: 10
});
module.exports = pool;
Dengan mengekspor pool
, kita bisa melakukan query di bagian lain aplikasi menggunakan pool tersebut.
4. Membuat Struktur Dasar Aplikasi di app.js
Kita akan membuat file utama bernama app.js
:
require('dotenv').config();
const express = require('express');
const cors = require('cors');
const app = express();
// Middleware
app.use(cors());
app.use(express.json());
// Routes
const userRoutes = require('./routes/userRoutes');
app.use('/api/users', userRoutes);
// Jalankan server
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server berjalan di port ${PORT}`);
});
Penjelasan ringkas:
- Memuat Variabel Lingkungan:
require('dotenv').config();
- Mengimpor Express dan cors: Agar kita dapat mengelola request/response dengan mudah dan mengizinkan cross-origin jika dibutuhkan.
express.json()
: Otomatis mem-parsing request body JSON yang dikirim klien.- Routing: Kita memisahkan rute terkait
users
ke dalamuserRoutes
, sehingga lebih terstruktur. - Menjalankan Server: Kita menentukan port, defaultnya 3000 jika
.env
tidak menyediakan.
5. Routing dan Controller
5.1. File userRoutes.js
Buat file routes/userRoutes.js
untuk mendefinisikan URL endpoints terkait user:
const express = require('express');
const router = express.Router();
const userController = require('../controllers/userController');
// CREATE
router.post('/', userController.createUser);
// READ
router.get('/', userController.getAllUsers);
router.get('/:id', userController.getUserById);
// UPDATE
router.put('/:id', userController.updateUser);
// DELETE
router.delete('/:id', userController.deleteUser);
module.exports = router;
Di sini, kita mendefinisikan empat method HTTP untuk operasi CRUD:
POST /api/users
untuk createGET /api/users
danGET /api/users/:id
untuk readPUT /api/users/:id
untuk updateDELETE /api/users/:id
untuk delete
Setiap endpoint akan memanggil fungsi dari userController
.
5.2. File userController.js
Sekarang buat file controllers/userController.js
untuk menampung logika masing-masing endpoint:
const pool = require('../config/db');
// CREATE
exports.createUser = (req, res) => {
const { name, email, age } = req.body;
const sql = 'INSERT INTO users (name, email, age) VALUES (?, ?, ?)';
pool.query(sql, [name, email, age], (err, result) => {
if (err) {
return res.status(500).json({ error: err.message });
}
// result.insertId berisi ID user yang baru ditambahkan
res.status(201).json({ message: 'User ditambahkan', userId: result.insertId });
});
};
// READ - GET ALL USERS
exports.getAllUsers = (req, res) => {
const sql = 'SELECT * FROM users';
pool.query(sql, (err, rows) => {
if (err) {
return res.status(500).json({ error: err.message });
}
res.json(rows);
});
};
// READ - GET USER BY ID
exports.getUserById = (req, res) => {
const userId = req.params.id;
const sql = 'SELECT * FROM users WHERE id = ?';
pool.query(sql, [userId], (err, rows) => {
if (err) {
return res.status(500).json({ error: err.message });
}
if (rows.length === 0) {
return res.status(404).json({ message: 'User tidak ditemukan' });
}
res.json(rows[0]);
});
};
// UPDATE
exports.updateUser = (req, res) => {
const userId = req.params.id;
const { name, email, age } = req.body;
const sql = 'UPDATE users SET name = ?, email = ?, age = ? WHERE id = ?';
pool.query(sql, [name, email, age, userId], (err, result) => {
if (err) {
return res.status(500).json({ error: err.message });
}
if (result.affectedRows === 0) {
return res.status(404).json({ message: 'User tidak ditemukan' });
}
res.json({ message: 'User diperbarui' });
});
};
// DELETE
exports.deleteUser = (req, res) => {
const userId = req.params.id;
const sql = 'DELETE FROM users WHERE id = ?';
pool.query(sql, [userId], (err, result) => {
if (err) {
return res.status(500).json({ error: err.message });
}
if (result.affectedRows === 0) {
return res.status(404).json({ message: 'User tidak ditemukan' });
}
res.json({ message: 'User dihapus' });
});
};
Penjelasan Singkat:
createUser
: Menambahkan data pengguna baru. Jika sukses, balas dengan kode HTTP 201 (Created) dan kembalikan ID data yang baru tersimpan.getAllUsers
: Mengambil semua data users dari tabel. Kembalikan hasil query berbentuk array JSON.getUserById
: Mengambil data user berdasarkan id yang diambil dari parameter URL.updateUser
: Memperbarui data user berdasarkan id. Jika id tidak ditemukan, balas dengan 404 (Not Found).deleteUser
: Menghapus data user tertentu. Jika data tidak ditemukan, balas dengan 404.
Fungsi-fungsi ini menggunakan callback bawaan dari pool.query
. Jika ingin menggunakan pendekatan async/await, kita bisa memanfaatkan pool.promise()
dari mysql2
.
6. Pengujian Aplikasi CRUD
6.1. Menjalankan Server
Setelah semua file siap, jalankan perintah:
node app.js
Jika ingin agar server otomatis restart ketika ada perubahan kode, bisa memakai nodemon:
npx nodemon app.js
Di terminal, akan muncul pesan semacam:
Server berjalan di port 3000
Itu berarti server sudah aktif.
6.2. Menguji dengan Postman atau cURL
Gunakan alat seperti Postman, Insomnia, atau cURL untuk mengetes setiap endpoint.
-
Create (POST)
POST http://localhost:3000/api/users Body (JSON): { "name": "Budi", "email": "budi@example.com", "age": 25 }
Jika sukses, respon:
{ "message": "User ditambahkan", "userId": 1 }
-
Read All (GET)
GET http://localhost:3000/api/users
Respon (contoh):
[ { "id": 1, "name": "Budi", "email": "budi@example.com", "age": 25 } ]
-
Read by ID (GET)
GET http://localhost:3000/api/users/1
Respon (contoh):
{ "id": 1, "name": "Budi", "email": "budi@example.com", "age": 25 }
-
Update (PUT)
PUT http://localhost:3000/api/users/1 Body (JSON): { "name": "Budi Sukamto", "email": "budi_s@example.com", "age": 26 }
Respon (contoh):
{ "message": "User diperbarui" }
-
Delete (DELETE)
DELETE http://localhost:3000/api/users/1
Respon (contoh):
{ "message": "User dihapus" }
Jika setiap endpoint bekerja dengan benar, artinya proses CRUD berhasil.
7. Tips dan Peningkatan
-
Validasi Input
Gunakan library sepertijoi
atauexpress-validator
untuk memvalidasi data yang dikirim oleh klien. Ini mencegah data tidak valid masuk ke database. -
Struktur MVC atau Clean Architecture
Untuk aplikasi berskala besar, pertimbangkan membuat lapisan service atau repository agar logika bisnis lebih terpisah dari logika database. -
Error Handling Lebih Lanjut
Buat error middleware khusus di Express. Dengan begitu, penanganan error lebih terorganisir. Contoh:app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ error: 'Terjadi masalah pada server' }); });
-
Penggunaan ORM
Jika ingin lebih fleksibel atau memakai fitur migrations, gunakan ORM seperti Sequelize, TypeORM (untuk TS), atau Prisma. ORM sering memudahkan dalam mengelola relasi tabel dan migrasi skema database. -
Keamanan
- Pastikan tidak pernah membocorkan kredensial database di repositori publik.
- Selalu filter input agar tidak rentan terhadap SQL Injection. Meskipun
mysql2
mendukung prepared statements lewat parameter array, tetap berhati-hati. - Pertimbangkan untuk menambahkan autentikasi & otorisasi (JWT atau session) jika aplikasi memerlukan akses terbatas.
-
Menerapkan ke Produksi
- Gunakan platform seperti Heroku, Railway, AWS, atau VPS.
- Pakai
pm2
atau sistem process manager lain untuk menjaga agar Node.js tetap berjalan. - Tambahkan SSL (HTTPS) agar data yang dikirim lebih aman.
8. Mengadaptasi ke MongoDB
Jika lebih suka database NoSQL seperti MongoDB, alurnya masih serupa:
- Install
mongoose
. - Buat file koneksi
db.js
menggunakanmongoose.connect
. - Definisikan schema dan model di folder
models/
. - Ganti logika controller agar menggunakan method Mongoose (
Model.find
,Model.create
, dll.) dibanding query SQL.
Contoh koneksi db.js
dengan MongoDB Atlas:
require('dotenv').config();
const mongoose = require('mongoose');
mongoose.connect(process.env.MONGO_URI, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => console.log('Terhubung ke MongoDB'))
.catch(err => console.error('Gagal terkoneksi ke MongoDB:', err));
module.exports = mongoose;
Setelah itu, kita bisa membuat file userModel.js
:
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: String,
email: String,
age: Number
});
module.exports = mongoose.model('User', userSchema);
Sedangkan di controller, kita tinggal panggil User.create
, User.find()
, User.findById
, User.findByIdAndUpdate
, dsb.
9. Contoh Penggunaan di Frontend
Jika ingin memanggil API CRUD ini dari aplikasi frontend (misal React, Vue, atau Angular), cukup arahkan request ke endpoint yang telah dibuat. Contohnya, di React:
// Mengambil daftar pengguna
fetch('http://localhost:3000/api/users')
.then(response => response.json())
.then(data => console.log(data));
// Menambahkan pengguna baru
fetch('http://localhost:3000/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Andi', email: 'andi@example.com', age: 23 })
})
.then(response => response.json())
.then(result => console.log(result));
Struktur respons yang dikembalikan server akan sama seperti pengujian manual di Postman.
10. Ringkasan Alur
- Inisialisasi Proyek: Buat folder, jalankan
npm init -y
, install dependencies. - Struktur Direktori: Pisahkan file koneksi database, routes, controller, dan file utama
app.js
. - Konfigurasi Database: Lengkapi file
.env
untuk menyimpan detail koneksi. - Definisikan Routes: Pada
routes/userRoutes.js
, buat rute untukPOST
,GET
,PUT
, danDELETE
. - Implementasi Controller: Di
controllers/userController.js
, buat fungsi untuk tiap operasi CRUD. Lakukan query ke database. - Jalankan dan Uji: Gunakan Postman atau cURL untuk memastikan semua rute berjalan sesuai harapan.
- Pengembangan Lanjutan: Tambahkan validasi, autentikasi, dan model data yang lebih kompleks. Pertimbangkan ORM atau library lain sesuai kebutuhan.
Baca Juga :