Migrasi dari Monolith ke Microservices
Jangan rewrite dari nol. Migrasi harus incremental — extract service satu per satu sambil monolith tetap berjalan.
Strangler Fig Pattern
Seperti tanaman strangler fig yang perlahan menggantikan pohon host. Route traffic ke service baru satu endpoint pada satu waktu.
Phase 1: Semua traffic → Monolith
Phase 2: /api/payments → Payment Service (baru)
Sisanya → Monolith
Phase 3: /api/payments → Payment Service
/api/inventory → Inventory Service (baru)
Sisanya → Monolith
Phase N: Monolith kosong, bisa di-retire
Steps
- Identify boundaries — Gunakan DDD bounded context. Mulai dari domain yang paling independen.
- Build new service — Service baru dengan database sendiri.
- Create anti-corruption layer — Adapter antara monolith dan service baru.
- Migrate data — Sync data dari monolith DB ke service DB (dual-write atau CDC).
- Route traffic — Pindahkan traffic ke service baru (feature flag atau API gateway).
- Remove old code — Hapus kode lama dari monolith.
Database Decomposition
// Paling sulit: memisahkan database
// Step 1: Logical separation (shared DB, separate schemas)
monolith_db.orders → order_schema.orders
monolith_db.payments → payment_schema.payments
// Step 2: Introduce API calls
Order Service → HTTP/gRPC → Payment Service
(bukan direct DB query lagi)
// Step 3: Physical separation
order_service_db (PostgreSQL)
payment_service_db (PostgreSQL)
// Data sync via events/CDC selama transisi
Common Mistakes
- Big bang rewrite — Terlalu berisiko, selalu over deadline
- Distributed monolith — Microservices yang masih coupled (shared DB, sync calls everywhere)
- Too small services — "Nano-services" yang menambah complexity tanpa benefit
- Premature decomposition — Belum perlu microservices? Jangan dipaksa.
🎭 Analogi sehari-hari
Renovasi rumah sambil tinggal di dalamnya. Kamu gak boleh bongkar semua sekaligus — gak ada tempat tidur. Strategi: renovasi satu kamar pada satu waktu. Pindah ke kamar tamu, renovasi kamar tidur. Selesai? Pindah ke kamar tidur baru, renovasi kamar tamu. Pelan tapi rumah tetap fungsional. Itulah Strangler Fig — extract microservice satu per satu sambil monolith tetap jalan.
💡 Mengapa "Big Bang Rewrite" hampir selalu gagal
- Joel Spolsky: "rewrite from scratch = single worst strategic mistake any company can make"
- Business tidak berhenti selama rewrite — fitur baru tetap ditambahkan ke monolith → microservices baru ketinggalan terus
- Domain knowledge hilang — bug subtle di monolith adalah fitur bagi user, rewrite gak tahu
- Deadline meluncur — selalu 2x lebih lama dari estimasi
- Risk all-or-nothing — kalau rewrite gagal, balik ke 0
⚠️ Jebakan klasik migrasi
- Distributed monolith = microservices tapi shared DB + sync calls everywhere = worst of both
- Wrong boundaries = service boundary salah → tiap fitur baru butuh ubah 5 service
- Database split terlalu cepat = data inconsistency selama migrasi. Pakai logical separation dulu
- Tidak punya feature flag / canary = rollback susah saat ada bug
- Tidak ada anti-corruption layer = service baru terinfeksi model lama
- Skip observability = bug muncul di production tapi gak tahu service mana yang salah
- Migrasi tanpa exit criteria = monolith 50% extract selamanya = 2x maintenance cost
🎯 Migration checklist
- Identify boundary via DDD bounded context
- Pick service paling independen dulu (e.g., notification, search) — risk rendah
- Build new service dengan database sendiri
- Anti-corruption layer antar service baru ↔ monolith
- Dual-write atau CDC sync data selama transition
- Feature flag untuk gradual rollout (1% traffic dulu)
- Monitor error rate + latency comparison old vs new
- Cutover 100% traffic, hapus code lama dari monolith
- Repeat untuk service berikut
- Define exit criteria — kapan dianggap migrasi selesai
TL;DR: Migrasi monolith → microservices = incremental via Strangler Fig pattern. Big bang rewrite hampir selalu gagal. Wajib DDD untuk boundary, anti-corruption layer, feature flag, observability. Mulai dari service paling independen. Database split paling sulit — logical dulu, physical kemudian. Define exit criteria supaya gak stuck di "half-migrated" forever.