Struktur Project Node.js Siap Produksi
Admin
Penulis Artikel
Struktur Project Node.js Siap Produksi: Boilerplate Backend dari Nol
Selama delapan artikel sebelumnya, kita membangun Todo List API sepotong demi sepotong: mulai dari merapikan kode CRUD jadi folder Controller-Service-Model, menambahkan middleware & .env, error handling yang benar, autentikasi JWT & role-based access, proteksi API Key, validasi & pagination, automated testing dengan Jest, sampai dokumentasi dengan Postman & Swagger.
Analogi: kalau delapan artikel sebelumnya itu ibarat merakit sebuah sepeda komponen demi komponen — rangka dulu, lalu rem, lalu gir, lalu lampu — artikel ini adalah langkah terakhir menaiki sepeda itu secara utuh dan mengecek semua bagiannya berfungsi bersama-sama. Kita tidak akan menambahkan fitur baru di sini. Tujuannya murni menyatukan semua yang sudah dibangun jadi satu boilerplate yang bisa langsung kamu pakai sebagai starter project di proyek nyata.
Artikel ini merangkum seluruh project Todo List API dari artikel pertama hingga kedelapan. Setelah ini, seri akan ditutup dengan dua artikel pendukung: Cara Menulis README.md yang Profesional dan Panduan Push Project ke GitHub.
1. Struktur Folder Final
Berikut struktur folder lengkap Todo List API setelah melewati seluruh seri artikel:
todo-api/
├── src/
│ ├── config/
│ │ ├── db.js (artikel #1, diupdate #2)
│ │ └── swagger.js (artikel #8)
│ ├── middlewares/
│ │ ├── logger.middleware.js (artikel #2)
│ │ ├── notFound.middleware.js (artikel #2, diupdate #3)
│ │ ├── errorHandler.middleware.js (artikel #2, diupdate #3)
│ │ ├── auth.middleware.js (artikel #4)
│ │ ├── restrictTo.middleware.js (artikel #4)
│ │ ├── apiKey.middleware.js (artikel #5)
│ │ └── validate.middleware.js (artikel #6)
│ ├── validators/
│ │ └── todo.validator.js (artikel #6)
│ ├── models/
│ │ ├── todo.model.js (artikel #1, diupdate #4)
│ │ └── user.model.js (artikel #4)
│ ├── services/
│ │ ├── todo.service.js (artikel #1, diupdate #4, #5, #6)
│ │ └── auth.service.js (artikel #4)
│ ├── controllers/
│ │ ├── todo.controller.js (artikel #1, diupdate #3, #4, #6)
│ │ ├── auth.controller.js (artikel #4)
│ │ └── stats.controller.js (artikel #5)
│ ├── routes/
│ │ ├── todo.routes.js (artikel #1, diupdate #4, #6, #8)
│ │ ├── auth.routes.js (artikel #4, diupdate #8)
│ │ └── stats.routes.js (artikel #5, diupdate #8)
│ ├── utils/
│ │ ├── AppError.js (artikel #3)
│ │ └── catchAsync.js (artikel #3)
│ ├── app.js (artikel #1, diupdate tiap artikel)
│ └── server.js (artikel #1, diupdate #2)
├── tests/
│ ├── setup.js (artikel #7)
│ ├── auth.test.js (artikel #7)
│ ├── todo.test.js (artikel #7)
│ └── stats.test.js (artikel #7)
├── jest.config.js (artikel #7)
├── .env
├── .env.test (artikel #7)
├── .env.example
├── .gitignore
└── package.json
Penjelasan teknis: perhatikan bagaimana setiap folder punya satu tanggung jawab spesifik — ini adalah hasil akhir dari prinsip separation of concerns yang kita mulai terapkan sejak artikel pertama. Kalau ada bug di validasi input, kamu tahu harus buka folder validators/. Kalau ada masalah otorisasi, kamu tahu harus cek middlewares/auth.middleware.js atau restrictTo.middleware.js. Struktur seperti ini yang membuat project mudah dinavigasi meskipun sudah punya puluhan file, dan menjadi alasan kenapa pola ini dipakai luas di project backend profesional.
2. package.json Final
Berikut package.json lengkap dengan seluruh dependency yang terkumpul dari artikel #1 sampai #8:
{
"name": "todo-api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node src/server.js",
"dev": "nodemon src/server.js",
"test": "jest --runInBand --detectOpenHandles"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "commonjs",
"dependencies": {
"bcryptjs": "^3.0.3",
"dotenv": "^17.4.2",
"express": "^5.2.1",
"express-validator": "^7.3.2",
"jsonwebtoken": "^9.0.3",
"mongoose": "^9.7.4",
"swagger-jsdoc": "^6.3.0",
"swagger-ui-express": "^5.0.1"
},
"devDependencies": {
"jest": "^30.4.2",
"mongodb-memory-server": "^11.2.0",
"nodemon": "^3.1.14",
"supertest": "^7.2.2"
}
}
Penjelasan teknis: perhatikan pembagian dependencies vs devDependencies. Package di dependencies (seperti express, mongoose, bcryptjs) benar-benar dibutuhkan aplikasi untuk berjalan di production. Package di devDependencies (seperti jest, nodemon, supertest) hanya dibutuhkan selama development dan testing — saat aplikasi di-deploy ke server production nanti, package di devDependencies ini bisa dilewati (lewat npm install --production) supaya ukuran deployment lebih kecil dan lebih cepat.
2.1 Instalasi dari Nol
Kalau kamu memulai project ini benar-benar dari nol (bukan lanjutan dari artikel-artikel sebelumnya), berikut kumpulan perintah install yang setara dengan package.json di atas:
npm init -y
npm install express mongoose dotenv bcryptjs jsonwebtoken express-validator swagger-jsdoc swagger-ui-express
npm install --save-dev nodemon jest supertest mongodb-memory-server
3. Environment Variables Final
.env.example (final, kumpulan seluruh variabel dari artikel #2, #4, #5)
PORT=3000
MONGODB_URI=mongodb://127.0.0.1:27017/todo_api_db
NODE_ENV=development
JWT_SECRET=isi-dengan-secret-kamu-sendiri
JWT_EXPIRES_IN=1d
EXTERNAL_API_KEY=isi-dengan-api-key-kamu-sendiri
Penjelasan teknis: tiga blok variabel ini merepresentasikan tiga “lapisan kepercayaan” berbeda yang kita bangun sepanjang seri ini: MONGODB_URI untuk koneksi database (artikel #2), JWT_SECRET untuk memverifikasi identitas user yang login (artikel #4), dan EXTERNAL_API_KEY untuk memverifikasi aplikasi eksternal yang mengakses endpoint statistik (artikel #5). Ingat, file .env yang sungguhan (bukan .env.example) tidak boleh pernah ikut ter-commit ke Git — ini akan dibahas lebih detail di artikel push ke GitHub.
4. Peta Referensi Setiap File
Karena kode lengkap tiap file sudah dibahas detail di artikel masing-masing, tabel di bawah ini berfungsi sebagai peta rujukan cepat — kalau kamu lupa isi atau alasan di balik satu file tertentu, tinggal buka artikel yang tertera.
File | Fungsi Singkat | Rujukan Lengkap |
|---|---|---|
| Koneksi ke MongoDB via Mongoose, membaca | |
| Konfigurasi OpenAPI: info API, securitySchemes, schema Todo | |
| Mencatat tiap request masuk (method, URL, durasi) | |
| Menangani endpoint yang tidak terdaftar (404) | |
| Menangani semua error terpusat, menerjemahkan ke status code & pesan yang tepat | |
| Verifikasi token JWT (autentikasi) | |
| Membatasi akses berdasarkan role (otorisasi) | |
| Verifikasi API key untuk endpoint machine-to-machine | |
| Membaca hasil express-validator, hentikan request jika gagal | |
| Aturan validasi input untuk tiap endpoint todo | |
| Schema Mongoose untuk todo, termasuk field owner | |
| Schema Mongoose untuk user, hashing password otomatis | |
| Business logic todo: CRUD, filter, pagination, sorting, statistik | |
| Business logic register & login, generate token JWT | |
| Jembatan HTTP untuk endpoint todo, cek kepemilikan data | |
| Jembatan HTTP untuk register & login | |
| Jembatan HTTP untuk endpoint ringkasan statistik | |
| Endpoint CRUD todo, dilindungi JWT + validasi + didokumentasikan Swagger | |
| Endpoint register & login | |
| Endpoint statistik, dilindungi API key + didokumentasikan Swagger | |
| Custom Error class dengan status code bawaan | |
| Wrapper agar controller async tidak perlu try-catch manual | |
| Menyatukan semua middleware, route, dan Swagger UI | |
| Entry point, memuat .env dan menjalankan server | |
| Automated test untuk auth, todo, dan stats |
5. Quick Start: Menjalankan Boilerplate dari Nol
Analogi: bagian ini seperti petunjuk perakitan di kotak sepeda yang baru dibeli — urutan langkah yang harus diikuti supaya sepedanya benar-benar bisa dinaiki, bukan cuma tumpukan komponen lepas.
# 1. Clone atau salin project ke komputermu, lalu masuk ke foldernya
cd todo-api
# 2. Install seluruh dependency
npm install
# 3. Salin .env.example menjadi .env, lalu isi nilai-nilai sesuai kebutuhanmu
cp .env.example .env
# 4. Pastikan MongoDB sudah berjalan (lokal atau lewat MongoDB Atlas)
# 5. Jalankan server dalam mode development
npm run dev
# 6. Di terminal terpisah, jalankan seluruh automated test
npm test
Penjelasan teknis: urutan ini bukan kebetulan. .env harus disiapkan sebelum server dijalankan, karena server.js memanggil require("dotenv").config() di baris paling awal (artikel #2) — kalau file .env belum ada atau nilainya kosong, connectDB() di db.js akan langsung melempar error dan menghentikan proses (process.exit(1)), karena kita sengaja membuatnya fail-fast daripada membiarkan server berjalan dengan konfigurasi yang salah.
Setelah server berjalan, tiga hal ini bisa langsung diakses:
URL | Fungsi |
|---|---|
| Cek server hidup (health check sederhana) |
| Dokumentasi interaktif Swagger UI |
| Endpoint API sungguhan (butuh token/API key sesuai kebutuhan) |
6. Checklist Kesiapan Production
Gunakan checklist ini setiap kali kamu memulai project baru berbasis boilerplate ini, untuk memastikan tidak ada langkah penting yang terlewat:
Aspek | Sudah Diimplementasikan? | Rujukan |
|---|---|---|
Struktur folder terpisah per tanggung jawab | ✅ | Artikel #1 |
Konfigurasi lewat environment variable, bukan hardcode | ✅ | Artikel #2 |
Logging setiap request | ✅ | Artikel #2 |
Error response yang konsisten & status code yang tepat | ✅ | Artikel #3 |
Autentikasi (siapa penggunanya) | ✅ | Artikel #4 |
Otorisasi (apa yang boleh diakses) | ✅ | Artikel #4 |
Password di-hash, tidak pernah disimpan mentah | ✅ | Artikel #4 |
Proteksi akses machine-to-machine | ✅ | Artikel #5 |
Validasi input di setiap endpoint | ✅ | Artikel #6 |
Pagination untuk data dalam jumlah besar | ✅ | Artikel #6 |
Automated test untuk skenario utama | ✅ | Artikel #7 |
Dokumentasi API yang bisa dicoba langsung | ✅ | Artikel #8 |
README yang menjelaskan cara pakai project | ⏳ (artikel berikutnya) | Artikel #10 |
Version control & repository online | ⏳ (artikel berikutnya) | Artikel #11 |
7. Perjalanan Kita Sejauh Ini
Tahap | Sebelum Seri Ini | Setelah Seri Ini |
|---|---|---|
Struktur kode | Kumpulan function di satu file | Folder terpisah: config, middleware, model, service, controller, route, util, test |
Akses data | Array di memori, hilang saat restart | MongoDB lewat Mongoose, permanen |
Keamanan | Tidak ada | JWT, RBAC, API key, password hashing |
Kualitas input | Tidak divalidasi | Divalidasi lewat express-validator di setiap endpoint |
Penanganan error | Server bisa crash / pesan tidak konsisten | Terpusat, status code tepat, tidak pernah crash |
Pengujian | Tidak ada | Automated test (Jest + Supertest) & manual (Postman) |
Dokumentasi | Tidak ada | Interaktif lewat Swagger UI |
8. Kesimpulan
Todo List API yang kita bangun sepanjang seri ini bukan sekadar contoh latihan — strukturnya sengaja dirancang mengikuti pola yang benar-benar dipakai di banyak project backend profesional: pemisahan tanggung jawab yang jelas, keamanan berlapis, validasi ketat, pengujian otomatis, dan dokumentasi yang hidup berdampingan dengan kode. Kamu bisa memakai struktur folder dan pola-pola di artikel ini sebagai starter project untuk tugas atau proyek magangmu berikutnya, tinggal ganti Todo dengan resource lain sesuai kebutuhan (misalnya Product, Order, Article, dan seterusnya) — pola Controller-Service-Model, middleware, error handling, auth, validasi, testing, dan dokumentasinya tetap bisa dipakai ulang.
Satu hal yang belum kita sentuh: bagaimana menjelaskan semua ini ke orang lain yang baru pertama kali membuka project-mu, dan bagaimana membagikan project ini secara online lewat GitHub. Dua topik ini akan menutup seri kita.
Lanjutkan ke artikel berikutnya: Cara Menulis README.md yang Profesional untuk Project Backend Node.js
Artikel Terkait
Panduan Membuat Animasi Animated on Scroll di Website Anda
Pelajari cara membuat animasi menarik pada scroll di website Anda dengan tutorial ini. Tampilkan konten dengan cara yang lebih interaktif!
Cara Menangani Error dan HTTP Status Code yang Benar
cara menentukan HTTP status code yang benar untuk tiap jenis error, dan cara membuat custom Error
Cara Restrukturisasi CRUD Node.js: Dari Function ke Folder Controller-Service-Model
cara merestrukturisasi kode CRUD dari kumpulan function menjadi struktur folder yang rapi menggunakan pola Controller-Service-Model.
