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 #

AspekSQLite (tertanam)PostgreSQL / MySQL (client-server)
Tempat berjalanDi dalam proses Node.jsProses terpisah, biasanya di mesin lain
Pengelolaan berkasSatu berkas database biasaServer mengelola berkas sendiri
Protokol komunikasiTidak ada — pemanggilan function langsungProtokol jaringan lewat TCP
InstalasiTidak perlu — sudah ada di Node.js 22 ke atasPerlu memasang dan menyalakan server
Penulis serentakSatu penulis pada satu waktuBanyak klien menulis serentak
Cocok untukAplikasi kecil, prototipe, data lokal, pengujianAplikasi 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:

text Bentuk umum connection string PostgreSQL
postgresql://pengguna:YOUR_DATABASE_PASSWORD@localhost:5432/tugasdb

Enam bagian penyusunnya:

  1. Skema (postgresql://) — memberi tahu driver jenis database yang dituju; MySQL memakai mysql://.
  2. Pengguna (pengguna) — nama akun di server database.
  3. Kata sandi (YOUR_DATABASE_PASSWORD) — dipisahkan tanda titik dua; selalu simpan sebagai placeholder, bukan nilai nyata di dalam kode.
  4. Host (localhost) — alamat mesin tempat server database berjalan.
  5. Port (5432) — pintu TCP yang didengarkan server; 5432 adalah bawaan PostgreSQL, MySQL memakai 3306.
  6. 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:

js
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:

text
Hasil query: [{"id":1,"judul":"Belajar database driver","selesai":0}]
Koneksi ditutup

Mari kita telusuri kelima tahap pada kode di atas:

  1. Baris 4 (new DatabaseSync(':memory:')): koneksi dibuka ke database yang hidup sepenuhnya di memori — ideal untuk latihan karena tidak menyentuh filesystem sama sekali.
  2. Baris 7 (db.exec(...)): statement DDL untuk membuat tabel dieksekusi langsung tanpa parameter.
  3. Baris 10-11 (tulis.run(...)): statement INSERT dikompilasi sekali lalu dipanggil dengan satu parameter terikat (tanda tanya) — pola yang menjadi fokus Chapter Query Parameterized.
  4. Baris 14-15 (baca.all()): hasil query kembali sebagai array berisi object { id, judul, selesai }; method JSON.stringify dipakai agar strukturnya terlihat utuh di terminal.
  5. 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.