API manajemen tugas yang kita bangun pada Section REST API menyimpan data di sebuah Map di dalam memori proses. Selama proses berjalan, data tersebut tersimpan dengan baik; begitu proses berhenti atau server dinyalakan ulang, seluruh tugas menguap bersama memori. Aplikasi nyata membutuhkan penyimpanan yang bertahan melebihi umur proses, dan di sinilah database masuk. Sebelum menyentuh kode koneksi, kita perlu memahami satu lapisan perangkat lunak yang selalu ada di antara Node.js dan database: database driver. Chapter ini membahas peran driver, perbedaan database tertanam dan client-server, bentuk connection string, serta pola dasar siklus hidup koneksi.
Peran Database Driver #
Database driver adalah package yang menerjemahkan panggilan JavaScript menjadi pesan yang dipahami database, lalu menerjemahkan balasan database menjadi object JavaScript. PostgreSQL dan MySQL adalah program terpisah yang berkomunikasi lewat protokol jaringan; keduanya tidak mengerti JavaScript, dan JavaScript tidak mengerti protokol mereka. Driver seperti pg (PostgreSQL) dan mysql2 (MySQL) mengisi jurang tersebut: function query() yang kita panggil di kode pada akhirnya dikirim driver sebagai rangkaian byte melalui socket TCP, dan balasan berupa baris data dikembalikan sebagai array of object.
Node.js sendiri tidak membawa driver PostgreSQL maupun MySQL di core modules — kita menginstal driver lewat npm sesuai database yang dipakai. Satu pengecualian penting adalah SQLite: database ini berjalan tertanam di dalam proses aplikasi, sehingga Node.js menyediakannya langsung sebagai core module node:sqlite tanpa instalasi apa pun. Perbedaan mendasar kedua kelompok ini layak dibedah sebelum kita menulis kode.
Database Tertanam vs Client-Server #
| Aspek | SQLite (tertanam) | PostgreSQL / MySQL (client-server) |
|---|---|---|
| Tempat berjalan | Di dalam proses Node.js | Proses terpisah, biasanya di mesin lain |
| Pengelolaan berkas | Satu berkas database biasa | Server mengelola berkas sendiri |
| Protokol komunikasi | Tidak ada — pemanggilan function langsung | Protokol jaringan lewat TCP |
| Instalasi | Tidak perlu — sudah ada di Node.js 22 ke atas | Perlu memasang dan menyalakan server |
| Penulis serentak | Satu penulis pada satu waktu | Banyak klien menulis serentak |
| Cocok untuk | Aplikasi kecil, prototipe, data lokal, pengujian | Aplikasi multi-user, data besar, produksi |
SQLite membaca dan menulis langsung ke satu berkas di filesystem, sehingga seluruh operasi dapat berjalan secara sinkron tanpa jaringan. PostgreSQL dan MySQL menjalankan server yang menerima koneksi dari banyak klien sekaligus — termasuk proses Node.js kita. Konsekuensinya, setiap operasi ke database client-server menembus jaringan dan bersifat asynchronous; pola async/await yang kita kuasai pada Section Asynchronous Runtime menjadi kebutuhan utama.
Anatomi Connection String #
Untuk database client-server, driver perlu tahu ke mana harus terhubung dan dengan identitas apa. Informasi tersebut dirangkum dalam satu URL yang disebut connection string:
postgresql://pengguna:YOUR_DATABASE_PASSWORD@localhost:5432/tugasdbEnam bagian penyusunnya:
- Skema (
postgresql://) — memberi tahu driver jenis database yang dituju; MySQL memakaimysql://. - Pengguna (
pengguna) — nama akun di server database. - Kata sandi (
YOUR_DATABASE_PASSWORD) — dipisahkan tanda titik dua; selalu simpan sebagai placeholder, bukan nilai nyata di dalam kode. - Host (
localhost) — alamat mesin tempat server database berjalan. - Port (
5432) — pintu TCP yang didengarkan server; 5432 adalah bawaan PostgreSQL, MySQL memakai 3306. - Nama database (
tugasdb) — database spesifik di dalam server yang ingin dipakai.
Siklus Hidup Koneksi #
Apa pun drivernya, pola pemakaian selalu terdiri atas lima tahap yang sama: buka koneksi, kirim query, terima hasil, olah hasil, lalu tutup koneksi. Contoh berikut memperagakan siklus lengkap tersebut memakai node:sqlite — satu-satunya driver yang bisa kita jalankan langsung tanpa server eksternal:
import { DatabaseSync } from 'node:sqlite';
// Tahap 1: buka koneksi — driver mengelola satu sesi ke database.
const db = new DatabaseSync(':memory:');
// Tahap 2: definisikan struktur data.
db.exec('CREATE TABLE tugas (id INTEGER PRIMARY KEY, judul TEXT, selesai INTEGER)');
// Tahap 3: tulis data lewat query.
const tulis = db.prepare('INSERT INTO tugas (judul, selesai) VALUES (?, ?)');
tulis.run('Belajar database driver', 0);
// Tahap 4: baca hasil query sebagai object JavaScript.
const baca = db.prepare('SELECT id, judul, selesai FROM tugas');
console.log('Hasil query:', JSON.stringify(baca.all()));
// Tahap 5: tutup koneksi agar sumber daya dilepas.
db.close();
console.log('Koneksi ditutup');Output yang Dihasilkan:
Hasil query: [{"id":1,"judul":"Belajar database driver","selesai":0}]
Koneksi ditutupMari kita telusuri kelima tahap pada kode di atas:
- Baris 4 (
new DatabaseSync(':memory:')): koneksi dibuka ke database yang hidup sepenuhnya di memori — ideal untuk latihan karena tidak menyentuh filesystem sama sekali. - Baris 7 (
db.exec(...)): statement DDL untuk membuat tabel dieksekusi langsung tanpa parameter. - Baris 10-11 (
tulis.run(...)): statementINSERTdikompilasi sekali lalu dipanggil dengan satu parameter terikat (tanda tanya) — pola yang menjadi fokus Chapter Query Parameterized. - Baris 14-15 (
baca.all()): hasil query kembali sebagai array berisi object{ id, judul, selesai }; methodJSON.stringifydipakai agar strukturnya terlihat utuh di terminal. - Baris 18 (
db.close()): koneksi ditutup secara eksplisit. Pada driver berjaringan, langkah ini wajib lebih diperhatikan karena koneksi yang dibiarkan terbuka terus memakan sumber daya di server.
Peta konsep telah lengkap: driver menerjemahkan, connection string menunjuk tujuan, dan siklus buka-kirim-tutup menata cara kita memakainya. Langkah paling natural berikutnya adalah menguasai driver yang paling dekat dengan kita — node:sqlite yang sudah tersedia di dalam runtime — pada Chapter SQLite dengan node:sqlite.