Memahami Strangler Fig pattern untuk migrasi bertahap, modular monolith sebagai recommended starting point 2026 (package-by-feature, data isolation), dan kapan saatnya extract ke microservices berdasarkan kebutuhan nyata

Setelah di episode 16 kita memahami event-driven architecture dan CQRS, pada episode ini kita membahas topik yang sangat relevan di 2026: bagaimana bermigrasi dari monolith ke arsitektur yang lebih scalable? Jawabannya bukan "langsung ke microservices" — tapi perjalanan bertahap yang dimulai dari modular monolith.
Trend 2026 menunjukkan "microservices hangover" — banyak organisasi yang terlalu cepat ke microservices dan mengalami operational complexity yang berlebihan. Shopify, Stack Overflow, dan GitHub membuktikan bahwa modular monolith yang terstruktur bisa menangani scale ratusan juta pengguna.
Strangler Fig adalah pola migrasi di mana modul baru dibangun sebagai microservice, sementara modul lama tetap di monolith — secara bertahap "menjepit" monolith sampai tidak ada yang tersisa.
Phase 1: Monolith (100% traffic)
├── User module
├── Product module
├── Order module
└── Payment module
Phase 2: User extracted ke microservice
├── User Service (new) ← 100% user traffic
├── Product module (di monolith)
├── Order module (di monolith)
└── Payment module (di monolith)
Phase 3: Product extracted
├── User Service
├── Product Service (new)
├── Order module (di monolith)
└── Payment module (di monolith)
... dst sampai semua modul ter-extractModular monolith adalah monolith yang di-structure dengan module boundaries yang jelas — seperti microservices tapi dalam satu deployment.
src/
├── modules/
│ ├── user/
│ │ ├── api/ # Public API (interface)
│ │ ├── internal/ # Implementation detail
│ │ ├── model/ # Domain models
│ │ └── repository/ # Data access
│ ├── product/
│ │ ├── api/
│ │ ├── internal/
│ │ ├── model/
│ │ └── repository/
│ ├── order/
│ │ ├── api/
│ │ ├── internal/
│ │ ├── model/
│ │ └── repository/
│ └── payment/
│ ├── api/
│ ├── internal/
│ ├── model/
│ └── repository/
├── shared/ # Shared utilities (no business logic)
└── app.ts # Entry point, register modules✅ GOOD: modules/user/, modules/product/, modules/order/
→ Setiap module punya public API dan internal implementation
❌ BAD: controllers/, models/, services/, repositories/
→ Berdasarkan teknologi, bukan business capability
→ Memaksa cross-module dependenciesmodules/user/api/index.ts → Public API (export)
modules/user/internal/ → Internal (tidak bisa diakses dari luar module)
modules/user/model/ → Domain models (bisa di-share via API)Rule: modul hanya boleh akses modul lain lewat public API — tidak boleh import internal.
Setiap module punya schema sendiri:
- Schema: user_schema, product_schema, order_schema
- atau: shared database tapi tabel per module
- atau: database per module (mirip microservices)
Public API untuk akses data:
- Order module tidak boleh query tabel user langsung
- Harus lewat UserService.getUser(userId)| Aspek | Modular Monolith | Microservices |
|---|---|---|
| Deployment | Satu deployment | Deploy per service |
| Latency | In-process (very fast) | Network (ms overhead) |
| Data | Shared database (schema isolation) | Database per service |
| Scalability | Vertical + horizontal (load balancer) | Horizontal per service |
| Complexity | Rendah (satu codebase) | Tinggi (banyak service) |
| Technology | Satu stack | Polyglot |
| Team size | Cocok untuk 5-50 engineer | Cocok untuk 50+ engineer |
Extract dari modular monolith ke microservices ketika:
Tip
Modular monolith adalah recommended starting point untuk 2026. Shopify (ratusan juta pengguna), Stack Overflow, dan GitHub membuktikan bahwa monolith yang terstruktur bisa menangani scale besar. Mulai dari sini, extract ke microservices saat ada kebutuhan nyata.
Monolith dengan module boundaries:
- modules/user/
- modules/product/
- modules/order/
- modules/payment/
Public API interface per module
Schema isolation di databasePayment module → Payment Service (microservice)
- Payment Service punya database sendiri
- Order Service komunikasi ke Payment via gRPC
- Event: OrderCreated → Payment Worker → PaymentProcessedNotification module → Notification Service
- Event-driven: listen ke semua event
- Database sendiri untuk template dan delivery log
- Independen dari modul lainSetiap extraction tanyakan:
- Apakah ini menyelesaikan masalah nyata?
- Apakah operational complexity worth it?
- Apakah tim bisa manage service baru ini?
Jika tidak → tetap di modular monolith.Inti yang harus dibawa pulang:
Di episode 18 selanjutnya kita akan membahas serverless & edge architecture — Lambda/Cloud Run/Cloudflare Workers, cold start, edge computing, dan perbandingan cost/latency antara container, Lambda, dan edge worker. Serverless mengubah cara kita berpikir tentang deployment dan scaling!