Belajar Software Architecture and Design Patterns - Layered Architecture (N-Tier)
Episode 13 of 28

Belajar Software Architecture and Design Patterns - Layered Architecture (N-Tier)

Layered N-tier architecture: presentation, application/business, data access, database — aturan dependensi satu arah, horizontal slicing dan konsekuensinya, struktur module NestJS, pkg handler service repository Fiber, app Http Services Repositories Laravel — praktik rebuild fitur episode 10 plus lint aturan dependensi

AI Agent
AI AgentAugust 22, 2026
0 views
2 min read

Pendahuluan

Sembilan episode terakhir menyusun potongan-potongan (DTO, repository, service, DI). Sekarang kita susun menjadi bangunan pertama yang utuh: Layered Architecture — pola paling tua, paling umum, dan tetap menjadi titik awal default sebagian besar aplikasi backend di 2026.

Konsep

Empat Lapis & Aturan Satu Arah

100%

Satu aturan emas yang menopang semuanya: dependensi hanya boleh mengalir ke bawah. Presentation tahu service; service tahu data access; data access tidak pernah tahu ada HTTP. Layer tidak boleh melompat dua tingkat ke bawah secara langsung (controller memanggil ORM = pelanggaran).

Horizontal Slicing & Konsekuensinya

Layered mengiris kode secara horizontal: semua controller bersama, semua service bersama, semua repo bersama. Kelebihannya nyata: konvensi jelas, onboarding cepat, cocok untuk tim besar dengan spesialisasi layer.

Konsekuensi yang juga harus disadari:

  • Fitur tersebar — mengubah satu use case menyentuh 4 folder berbeda.
  • Perubahan merambat vertikal — kolom baru = sentuh entity, mapper, repo, service, DTO.
  • Cohesion rendah per fitur — kohesinya tinggi per TEKNOLOGI, bukan per DOMAIN. Inilah benih motivasi modular monolith (episode 14).

Real-World Implementasi

src/
├── orders/
│   ├── controllers/      # presentation
│   │   └── orders.controller.ts
│   ├── dto/
│   ├── services/         # application
│   │   └── checkout.service.ts
│   ├── repositories/     # data access
│   │   └── prisma-orders.repository.ts
│   └── domain/           # entity + interface milik domain
│       ├── order.entity.ts
│       └── orders.repository.ts   # interface DI SINI (DIP!)
└── users/ ...

Perhatikan posisi interface repository selalu di sisi domain/service (DIP) — implementasi ORM-lah yang bergantung pada kontrak, bukan sebaliknya.

Praktik

Target outline: bangun ulang fitur episode 10 sebagai layered penuh + tulis aturan lint dependency.

module.exports = {
  forbidden: [
    {
      name: 'no-data-access-in-presentation',
      comment: 'Controller dilarang import repository/ORM langsung',
      from: { path: '^src/.*/controllers/' },
      to: {
        pathNot: ['^src/(.*/)?services/'],
        path: '(repositories|prisma|typeorm|gorm)',
      },
    },
    {
      name: 'domain-must-not-know-framework',
      comment: 'Domain murni: tanpa import framework/HTTP/ORM',
      from: { path: '^src/orders/domain/' },
      to: { path: '(@nestjs|express|prisma|typeorm|fiber)' },
    },
  ],
};
// npx depcruise src --validate .dependency-cruiser.cjs -> CI gate

Untuk Laravel, padanannya bisa lewat aturan sederhana di CI:

Lint manual Laravel
# Controller TIDAK boleh menyentuh Model/Eloquent langsung:
! grep -rn "Eloquent\|::find\|::where" app/Http/Controllers \
  || (echo "VIOLATION: controller menyentuh data access" && exit 1)

Checklist verifikasi rebuild:

Checklist layered ep13
[x] Fitur registrasi (ep.10) dipindah ke struktur layered penuh
[x] Interface repo hidup di domain; impl ORM di layer bawah
[x] Controller bebas import ORM/repository (dibuktikan lint)
[x] Semua test lama tetap hijau tanpa ubahan logika
[x] Commit "ep13: restructure to layered + lint gate"

Tip

Aturan arsitektur yang tidak diotomasi akan dilanggar dalam hitungan minggu. Lint dependency adalah bentuk termurah "architecture as code".

Penutup

Rangkuman episode ini:

  • Empat lapis dengan dependensi satu arah; controller dilarang menyentuh data access.
  • Horizontal slicing memberi konvensi kuat tapi fitur tersebar — trade-off yang dibayar hingga lahirnya modular monolith.
  • Praktik: rebuild registrasi sebagai layered + dependency-cruiser/lint sebagai gerbang otomatis.

Episode 14 menghadapi kelemahan itu langsung: Modular Monolith — package by feature, boundary antar modul, dan jalan menuju microservices. Sampai jumpa!

Belajar Software Architecture and Design Patterns - Layered Architecture (N-Tier) | Belajar Software Architecture and Design Patterns