Koneksi ke MySQL dengan NodeJS
Sebelum memulai, pastikan kamu sudah:
- Menyelesaikan materi Membuat API dengan NodeJS dan Express
- Menginstal MySQL di komputermu
- Memiliki proyek Express yang sudah dibuat di materi sebelumnya
Instalasi Package MySQL
Mari kita tambahkan MySQL ke proyek Express yang sudah kita buat sebelumnya. Di terminal, masuk ke folder proyekmu dan jalankan:
npm install mysql2
Kita menggunakan mysql2
karena lebih modern dan mendukung fitur Promise.
Menambahkan Koneksi MySQL ke Express
Kita akan memodifikasi index.js
yang sudah kita buat sebelumnya. Tambahkan kode berikut di bagian atas file, setelah impor Express:
const express = require('express')
const mysql = require('mysql2')
const app = express()
app.use(express.json())
// Buat koneksi ke database
const connection = mysql.createConnection({
host: 'localhost', // Lokasi server MySQL
user: 'root', // Username MySQL
password: '', // Password MySQL
database: 'belajar' // Nama database
})
// Coba koneksi ke database
connection.connect((error) => {
if (error) {
console.error('Gagal koneksi ke database:', error);
return;
}
console.log('Berhasil koneksi ke database!');
});
// Buat tabel jika belum ada
connection.query(`
CREATE TABLE IF NOT EXISTS tasks (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(255) NOT NULL,
selesai BOOLEAN DEFAULT false
)
`, (error) => {
if (error) {
console.error('Gagal membuat tabel:', error);
return;
}
console.log('Tabel tasks siap digunakan!');
});
Mengubah API untuk Menggunakan MySQL
Sekarang kita akan mengubah API tasks yang sebelumnya menggunakan array di memori menjadi menggunakan MySQL. Ganti kode routes yang lama dengan yang baru:
// CREATE - Menambah tugas baru
app.post('/tasks', (req, res) => {
const task = {
nama: req.body.nama,
selesai: false
};
connection.query(
'INSERT INTO tasks SET ?',
task,
(error, results) => {
if (error) {
console.error('Gagal menambah tugas:', error);
res.status(500).json({ pesan: 'Gagal menambah tugas' });
return;
}
task.id = results.insertId;
res.json(task);
}
);
});
// READ - Mengambil semua tugas
app.get('/tasks', (req, res) => {
connection.query('SELECT * FROM tasks', (error, results) => {
if (error) {
console.error('Gagal mengambil data:', error);
res.status(500).json({ pesan: 'Gagal mengambil data' });
return;
}
res.json(results);
});
});
// UPDATE - Mengubah status tugas
app.put('/tasks/:id', (req, res) => {
const id = parseInt(req.params.id);
const { selesai } = req.body;
connection.query(
'UPDATE tasks SET selesai = ? WHERE id = ?',
[selesai, id],
(error, results) => {
if (error) {
console.error('Gagal mengubah tugas:', error);
res.status(500).json({ pesan: 'Gagal mengubah tugas' });
return;
}
if (results.affectedRows === 0) {
res.status(404).json({ pesan: 'Tugas tidak ditemukan' });
return;
}
res.json({ id, selesai });
}
);
});
// DELETE - Menghapus tugas
app.delete('/tasks/:id', (req, res) => {
const id = parseInt(req.params.id);
connection.query(
'DELETE FROM tasks WHERE id = ?',
[id],
(error, results) => {
if (error) {
console.error('Gagal menghapus tugas:', error);
res.status(500).json({ pesan: 'Gagal menghapus tugas' });
return;
}
if (results.affectedRows === 0) {
res.status(404).json({ pesan: 'Tugas tidak ditemukan' });
return;
}
res.json({ pesan: 'Tugas berhasil dihapus' });
}
);
});
// Pastikan ini tetap di bagian bawah file
app.listen(3000, () => {
console.log('Server berjalan di http://localhost:3000')
})
Mencoba API dengan Database
Kamu bisa mencoba API yang sudah terhubung ke database dengan cara yang sama seperti sebelumnya:
# Menambah tugas baru
curl -X POST http://localhost:3000/tasks \
-H "Content-Type: application/json" \
-d '{"nama": "Belajar MySQL"}'
# Melihat semua tugas
curl http://localhost:3000/tasks
# Menandai tugas selesai
curl -X PUT http://localhost:3000/tasks/1 \
-H "Content-Type: application/json" \
-d '{"selesai": true}'
# Menghapus tugas
curl -X DELETE http://localhost:3000/tasks/1
Tambahan: Menggunakan Promise dan Async/Await
Kode callback bisa membuat program sulit dibaca ketika ada banyak operasi database. Mari kita perbaiki dengan menggunakan Promise dan async/await.
1. Persiapan Koneksi Promise
Pertama, buat file baru bernama database.js
untuk mengelola koneksi database:
const mysql = require('mysql2/promise'); // Perhatikan /promise di sini
async function createConnection() {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'belajar'
});
return connection;
}
module.exports = createConnection;
2. Inisialisasi Aplikasi dengan Async
Sekarang kita ubah cara menginisialisasi aplikasi di index.js
. Tambahkan kode ini di bagian atas file:
const express = require('express');
const createConnection = require('./database');
const app = express();
app.use(express.json());
let connection;
// Fungsi untuk memulai aplikasi
async function initializeApp() {
try {
// Buat koneksi database
connection = await createConnection();
console.log('Berhasil koneksi ke database!');
// Buat tabel jika belum ada
await connection.query(`
CREATE TABLE IF NOT EXISTS tasks (
id INT AUTO_INCREMENT PRIMARY KEY,
nama VARCHAR(255) NOT NULL,
selesai BOOLEAN DEFAULT false
)
`);
console.log('Tabel tasks siap digunakan!');
// Mulai server
app.listen(3000, () => {
console.log('Server berjalan di http://localhost:3000');
});
} catch (error) {
console.error('Gagal menginisialisasi aplikasi:', error);
process.exit(1);
}
}
3. Mengubah Route Menggunakan Async/Await
Mari ubah route satu per satu:
- Route GET (Mengambil data):
app.get('/tasks', async (req, res) => {
try {
const [rows] = await connection.query('SELECT * FROM tasks');
res.json(rows);
} catch (error) {
console.error('Gagal mengambil data:', error);
res.status(500).json({ pesan: 'Gagal mengambil data' });
}
});
- Route POST (Menambah data):
app.post('/tasks', async (req, res) => {
try {
const task = {
nama: req.body.nama,
selesai: false
};
const [result] = await connection.query('INSERT INTO tasks SET ?', task);
task.id = result.insertId;
res.json(task);
} catch (error) {
console.error('Gagal menambah tugas:', error);
res.status(500).json({ pesan: 'Gagal menambah tugas' });
}
});
- Route PUT (Mengubah data):
app.put('/tasks/:id', async (req, res) => {
try {
const id = parseInt(req.params.id);
const [result] = await connection.query(
'UPDATE tasks SET selesai = ? WHERE id = ?',
[req.body.selesai, id]
);
if (result.affectedRows === 0) {
res.status(404).json({ pesan: 'Tugas tidak ditemukan' });
return;
}
res.json({ id, selesai: req.body.selesai });
} catch (error) {
console.error('Gagal mengubah tugas:', error);
res.status(500).json({ pesan: 'Gagal mengubah tugas' });
}
});
4. Menjalankan Aplikasi
Di bagian bawah file, panggil fungsi inisialisasi:
// Mulai aplikasi
initializeApp();
Tips Keamanan
-
Jangan Simpan Password di Kode
- Instal dotenv:
npm install dotenv
- Buat file
.env
:DB_HOST=localhost DB_USER=root DB_PASS=password_rahasia DB_NAME=belajar
- Tambahkan di awal
database.js
:require('dotenv').config(); const mysql = require('mysql2/promise'); async function createConnection() { const connection = await mysql.createConnection({ host: process.env.DB_HOST, user: process.env.DB_USER, password: process.env.DB_PASS, database: process.env.DB_NAME }); return connection; }
- Instal dotenv:
-
Hindari SQL Injection
- Selalu gunakan prepared statements (parameter ?) seperti yang sudah kita lakukan
- Jangan langsung masukkan input pengguna ke dalam query
-
Batasi Akses Database
- Buat user MySQL khusus untuk aplikasimu
- Berikan hak akses minimal yang diperlukan
Mengatasi Masalah Umum
1. Error “Connection refused” (Koneksi Ditolak)
Di Linux/macOS:
- Periksa status MySQL:
sudo service mysql status # untuk Linux brew services list # untuk macOS
- Jalankan MySQL jika belum aktif:
sudo service mysql start # untuk Linux brew services start mysql # untuk macOS
Di Windows:
- Buka Services (Layanan) dengan menekan
Windows + R
, ketikservices.msc
- Cari “MySQL” di daftar
- Klik kanan dan pilih “Start” jika belum berjalan
- Atau gunakan Command Prompt sebagai Administrator:
net start mysql
2. Error “Access denied” (Akses Ditolak)
Periksa Kredensial:
- Pastikan username dan password di file
.env
sudah benar - Coba login ke MySQL untuk memverifikasi:
mysql -u root -p
Berikan Akses ke Database:
- Login ke MySQL sebagai root
- Jalankan perintah berikut (ganti ‘usermu’ dengan username yang diinginkan):
CREATE USER 'usermu'@'localhost' IDENTIFIED BY 'passwordmu'; GRANT ALL PRIVILEGES ON belajar.* TO 'usermu'@'localhost'; FLUSH PRIVILEGES;
3. Error “Unknown database” (Database Tidak Ditemukan)
Buat Database Baru:
- Login ke MySQL:
mysql -u root -p
- Buat database:
CREATE DATABASE belajar;
- Verifikasi database sudah dibuat:
SHOW DATABASES;
4. Error “ER_NOT_SUPPORTED_AUTH_MODE” (Mode Autentikasi Tidak Didukung)
Ini sering terjadi di MySQL 8.0+. Untuk mengatasinya:
- Login ke MySQL sebagai root
- Jalankan:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password_baru'; FLUSH PRIVILEGES;
- Update password di file konfigurasi aplikasimu