- Bab 6 dari 9
- 30 menit
- 1 latihan kode
- 4 soal kuis
Database & ORM
Di bab ini (5 bagian)
Tujuan bab ini
Dalam bab ini, kita akan membahas cara mengelola data pada aplikasi Express. Kita memiliki tiga tujuan utama:
- Menghubungkan aplikasi Express ke database MongoDB menggunakan pustaka Mongoose.
- Menggunakan PostgreSQL dan Prisma 7 untuk mengakses data secara relasional.
- Melakukan berbagai operasi query dan menangani relasi data dengan aman.
Database adalah tempat aplikasi menyimpan semua data penggunanya. Tanpa database, data yang dikirimkan ke server akan hilang saat server dimatikan ulang. Kita akan mempelajari dua jenis database yang sangat populer di industri, yaitu NoSQL dan SQL, beserta alat bantu (ORM/ODM) yang membuat interaksi dengan database tersebut menjadi jauh lebih mudah.
Memilih Database dan ORM
Sebelum mulai menulis kode, mari pahami perbedaan dua kategori database yang sering digunakan dalam ekosistem Node.js.
Yang pertama adalah database SQL atau relasional. Contoh dari database ini adalah PostgreSQL, MySQL, dan SQLite. Database jenis ini sangat cocok jika data yang kamu miliki sangat terstruktur dan memiliki relasi yang kuat antar entitas. Misalnya, sebuah entitas pengguna memiliki banyak entitas postingan. Database SQL juga menjamin transaksi yang aman dengan standar ACID (Atomicity, Consistency, Isolation, Durability). Untuk berinteraksi dengan database SQL, pengembang Node.js biasanya menggunakan pustaka tambahan seperti Prisma, Drizzle, Sequelize, atau Knex.
Yang kedua adalah database NoSQL berbasis dokumen, dengan MongoDB sebagai contoh paling populer. MongoDB menawarkan skema yang lebih fleksibel, memungkinkan penyimpanan data bersarang (nested data), dan sangat mendukung proses iterasi pengembangan yang cepat. Jika struktur data aplikasimu sering berubah, NoSQL bisa menjadi pilihan yang menarik. Untuk berinteraksi dengan MongoDB di Node.js, pustaka yang menjadi standar industri adalah Mongoose, yang bertindak sebagai ODM (Object Data Modeling), atau bisa juga menggunakan driver asli MongoDB.
Alur Akses Data yang Disarankan
Saat membangun aplikasi yang berskala besar, meletakkan semua logika database di dalam file pemetaan rute (route) akan membuat kode berantakan. Terdapat sebuah konvensi atau alur akses data yang disarankan agar kodemu tetap rapi dan mudah dirawat.
Alur yang disarankan berjalan seperti ini: permintaan masuk melalui Route, kemudian Route memanggil Controller. Controller akan memanggil Service yang berisi logika bisnis aplikasi. Service inilah yang kemudian berinteraksi dengan Model atau ORM. Terakhir, Model akan meneruskan perintah tersebut ke dalam Database yang sesungguhnya. Dengan memisahkan tanggung jawab ini, kodemu akan lebih mudah diuji dan dikembangkan di masa depan.
Menghubungkan Express ke MongoDB dengan Mongoose
Mongoose adalah pustaka pemodelan objek elegan yang dirancang untuk bekerja pada lingkungan asinkron. Mongoose membantu kita mendefinisikan bentuk data (skema) sebelum menyimpannya ke dalam MongoDB, sehingga kita terhindar dari masuknya data yang tidak valid.
Membuat Skema dan Model
Mari kita lihat bagaimana cara mendefinisikan sebuah skema untuk data buku menggunakan Mongoose.
Pada kode di atas, kita menentukan tipe data untuk masing-masing kolom. Atribut required: true memastikan bahwa judul dan penulis wajib diisi. Atribut trim: true akan memotong spasi kosong di awal dan akhir teks. Kita juga bisa memberikan batasan minimum seperti min: 1000 untuk tahun rilis, dan nilai bawaan default: 0 untuk stok. Selain itu, opsi timestamps: true sangat berguna karena Mongoose akan otomatis membuat dan mengelola kolom createdAt dan updatedAt untuk setiap dokumen buku.
Menyambungkan Database dan Menjalankan CRUD
Setelah model siap, kita perlu menyambungkan aplikasi Express ke database MongoDB. Proses ini biasanya dilakukan saat server baru mulai menyala.
Dalam Express 5, menulis operasi CRUD (Create, Read, Update, Delete) di dalam pengontrol (controller) menjadi jauh lebih ringkas. Kita tidak perlu lagi menulis blok try/catch secara manual di setiap fungsi asinkron.
Berkat Express 5, jika ada kesalahan validasi data (misalnya pengguna lupa mengirim judul buku) atau database terputus saat pemanggilan await Book.create(), janji (promise) yang ditolak akan otomatis diteruskan ke penanganan error (error handler) bawaan Express. Kamu tidak perlu memanggil next(err) secara manual.
PostgreSQL dan Prisma 7
Jika proyekmu membutuhkan struktur data relasional dan tipe data yang ketat, PostgreSQL dengan Prisma 7 adalah kombinasi yang tangguh. Prisma bertindak sebagai ORM modern yang membaca skema datamu dan menghasilkan kode klien yang sepenuhnya memahami tipe data.
Persiapan dan Skema Prisma
Untuk memulai dengan Prisma, kamu perlu menginstal beberapa paket melalui terminal.
Perintah inisialisasi akan membuat file konfigurasi skema. Mari kita lihat contoh skema untuk pengguna dan postingan.
Skema Prisma di atas mendefinisikan dua entitas. Pengguna memiliki kolom id yang nilainya bertambah otomatis. Kolom email ditandai sebagai unik, yang artinya tidak boleh ada dua pengguna dengan alamat email yang sama. Relasi juga terjalin jelas: satu pengguna bisa memiliki banyak postingan (Post[]), dan setiap postingan tertaut pada pengguna tertentu melalui authorId.
Setelah membuat skema, jalankan npx prisma migrate dev --name init untuk menerapkan perubahan tersebut ke dalam tabel PostgreSQL sesungguhnya, lalu npx prisma generate untuk membuat klien database.
Koneksi Klien dan Query
Selanjutnya, kita akan mengatur klien database agar dapat digunakan oleh aplikasi.
Sekarang kita bisa menggunakan objek prisma untuk melakukan interaksi database di dalam rute Express. Prisma memiliki API yang sangat ekspresif untuk menangani pencarian, pembatasan halaman (pagination), dan mengambil data relasional sekaligus.
Satu hal yang sering menjadi kesalahan fatal adalah membocorkan data sensitif. Perhatikan penggunaan properti select pada kode di atas. Dengan mendefinisikan kolom mana saja yang bernilai true, kita memastikan kolom password sama sekali tidak diambil dari database dan tidak akan pernah terkirim sebagai balasan ke klien. Ini adalah praktik keamanan yang sangat disarankan.
Prisma juga mendukung transaksi atomik. Jika kamu harus membuat pengguna baru dan profilnya secara bersamaan, dan salah satunya gagal, kamu dapat menggunakan prisma.$transaction([...]) untuk membatalkan seluruh operasi sehingga datamu tetap konsisten.
Rangkuman
- Terdapat dua jenis database utama yang sering digunakan dengan Node.js: database relasional (SQL) seperti PostgreSQL dan database dokumen (NoSQL) seperti MongoDB.
- Alur aplikasi yang disarankan adalah merutekan permintaan (Route) menuju pengontrol (Controller), memproses logika bisnis (Service), lalu mengakses database melalui model (Model/ORM).
- Mongoose membantu mendefinisikan struktur skema MongoDB yang ketat, seperti tipe data, validasi, dan penambahan stempel waktu (timestamps) secara otomatis.
- Pada Express 5, kamu tidak perlu menulis blok tangkapan error manual pada fungsi pengontrol asinkron karena error otomatis diumpankan ke penanganan error Express.
- Prisma 7 dan PostgreSQL menawarkan integritas data relasional yang sangat kuat, mendukung pengambilan data terbatas dengan fitur
selectuntuk menjaga keamanan kata sandi.
Slide 30 sampai 35 dari deck Express.js 5. Penjelasan lengkapnya ada di mode Baca.
Selesaikan bab ini
- 1. Baca materi
- 2. Latihan kode (1)
- 3. Kuis (4 soal)
Latihan kode: Membangun Endpoint Asinkron Express 5
Lengkapi fungsi rute GET dan POST untuk buku menggunakan Express. Tersedia variabel db fiktif yang menyimulasikan basis data dengan metode asinkron db.findById(id) dan db.create(data). Rute GET pada /api/books/:id harus mengembalikan status 404 jika buku tidak ditemukan, dan rute POST pada /api/books harus merespons dengan status 201 bila berhasil. Kamu tidak perlu menulis try/catch.
Cek pemahaman
1Pada Express versi 5, pengembang harus selalu menambahkan blok `try/catch` di dalam pengontrol Mongoose agar aplikasi tidak mogok jika terjadi kesalahan koneksi.
2Berdasarkan materi, manakah urutan alur akses data yang paling disarankan saat membangun arsitektur aplikasi backend?
3Apa yang akan dikembalikan oleh kode berikut kepada klien jika pengguna mencari buku dengan ID yang tidak ada di dalam database?
export const detail = async (req, res) => { const book = await Book.findById(req.params.id); if (!book) return res.sendStatus(404); res.json(book); };4Saat menggunakan Prisma untuk mencari data pengguna, bagaimana cara terbaik untuk memastikan kolom kata sandi tidak ikut terkirim ke sisi klien?

