Struktur Project Node.js Siap Produksi

Tutorial
Jul 19, 2026
8 mnt baca
9 tayangan
Struktur Project Node.js Siap Produksi
A

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

config/db.js

Koneksi ke MongoDB via Mongoose, membaca MONGODB_URI dari .env

Artikel #2

config/swagger.js

Konfigurasi OpenAPI: info API, securitySchemes, schema Todo

Artikel #8

middlewares/logger.middleware.js

Mencatat tiap request masuk (method, URL, durasi)

Artikel #2

middlewares/notFound.middleware.js

Menangani endpoint yang tidak terdaftar (404)

Artikel #2 & Artikel #3

middlewares/errorHandler.middleware.js

Menangani semua error terpusat, menerjemahkan ke status code & pesan yang tepat

Artikel #2 & Artikel #3

middlewares/auth.middleware.js

Verifikasi token JWT (autentikasi)

Artikel #4

middlewares/restrictTo.middleware.js

Membatasi akses berdasarkan role (otorisasi)

Artikel #4

middlewares/apiKey.middleware.js

Verifikasi API key untuk endpoint machine-to-machine

Artikel #5

middlewares/validate.middleware.js

Membaca hasil express-validator, hentikan request jika gagal

Artikel #6

validators/todo.validator.js

Aturan validasi input untuk tiap endpoint todo

Artikel #6

models/todo.model.js

Schema Mongoose untuk todo, termasuk field owner

Artikel #1 & Artikel #4

models/user.model.js

Schema Mongoose untuk user, hashing password otomatis

Artikel #4

services/todo.service.js

Business logic todo: CRUD, filter, pagination, sorting, statistik

Artikel #1, Artikel #4, Artikel #5, Artikel #6

services/auth.service.js

Business logic register & login, generate token JWT

Artikel #4

controllers/todo.controller.js

Jembatan HTTP untuk endpoint todo, cek kepemilikan data

Artikel #1, Artikel #3, Artikel #4, Artikel #6

controllers/auth.controller.js

Jembatan HTTP untuk register & login

Artikel #4

controllers/stats.controller.js

Jembatan HTTP untuk endpoint ringkasan statistik

Artikel #5

routes/todo.routes.js

Endpoint CRUD todo, dilindungi JWT + validasi + didokumentasikan Swagger

Artikel #1, Artikel #4, Artikel #6, Artikel #8

routes/auth.routes.js

Endpoint register & login

Artikel #4 & Artikel #8

routes/stats.routes.js

Endpoint statistik, dilindungi API key + didokumentasikan Swagger

Artikel #5 & Artikel #8

utils/AppError.js

Custom Error class dengan status code bawaan

Artikel #3

utils/catchAsync.js

Wrapper agar controller async tidak perlu try-catch manual

Artikel #3

app.js

Menyatukan semua middleware, route, dan Swagger UI

Semua artikel

server.js

Entry point, memuat .env dan menjalankan server

Artikel #1 & Artikel #2

tests/*.test.js

Automated test untuk auth, todo, dan stats

Artikel #7



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

http://localhost:3000

Cek server hidup (health check sederhana)

http://localhost:3000/api-docs

Dokumentasi interaktif Swagger UI

http://localhost:3000/api/todos, dst.

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!

Baca Artikel
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

Baca Artikel
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.

Baca Artikel