# BAB 4: DESAIN STRATEGIS DENGAN PEMETAAN KONTEKS (CONTEXT MAPPING)
**Buku:** Domain-Driven Design Distilled  
**Penulis:** Vaughn Vernon  
**Penerjemah:** Everest ERP Architecture Team  

---

Pada bab-bab sebelumnya Anda telah mempelajari bahwa selain *Core Domain*, ada beberapa *Bounded Contexts* yang terkait dengan setiap proyek DDD. Semua konsep yang bukan merupakan bagian dari inisiatif inti dipindahkan ke salah satu dari beberapa *Bounded Contexts* lainnya.

Anda juga mempelajari bahwa *Core Domain* (seperti *Agile Project Management Context*) harus berintegrasi dengan *Bounded Contexts* lainnya (seperti *Collaboration Context*). Integrasi tersebut dikenal dalam DDD sebagai **Context Mapping (Pemetaan Konteks)**.

Sebuah *Context Mapping* direpresentasikan oleh garis penghubung di antara dua *Bounded Contexts*. Garis ini menunjukkan bahwa kedua konteks tersebut dipetakan dengan cara tertentu. Di sana akan terdapat dinamika hubungan antar-tim serta mekanisme integrasi teknis.

---

### Garis Pemetaan Konteks: Penerjemah Bahasa (*Language Translation*)

Mengingat bahwa di dalam dua *Bounded Contexts* yang berbeda terdapat dua *Ubiquitous Languages* yang berbeda, garis pemetaan ini mewakili **terjemahan yang terjadi di antara kedua bahasa tersebut**.

Sebagai ilustrasi, bayangkan dua tim perlu bekerja sama, tetapi mereka bekerja melintasi batas negara dan tidak berbicara dalam bahasa yang sama. Entah kedua tim tersebut memerlukan penerjemah (*interpreter*), atau salah satu/kedua tim harus belajar banyak tentang bahasa tim lainnya. Menggunakan penerjemah akan mengurangi beban kerja bagi kedua tim, namun dapat memakan waktu ekstra. Meskipun demikian, tim mungkin menganggap ini solusi yang jauh lebih baik daripada harus terus-menerus berganti bahasa asing dan merusak kemurnian model mereka sendiri.

Ketika kita berbicara tentang *Context Mapping*, yang menarik bagi kita adalah: **hubungan antar-tim seperti apa dan integrasi teknis macam apa yang direpresentasikan oleh garis di antara dua Bounded Contexts tersebut?** Batasan dan kontrak yang terdefinisi dengan baik di antara keduanya mendukung perubahan yang terkendali seiring berjalannya waktu.

---

### Jenis-Jenis Hubungan Pemetaan Konteks (*Kinds of Mappings*)

Berikut adalah jenis-jenis pola hubungan Context Mapping:

#### 1. Partnership (Kemitraan)
Hubungan kemitraan terjadi antara dua tim di mana masing-masing tim bertanggung jawab atas satu *Bounded Context*.
- Kedua tim menyelaraskan tujuan yang saling bergantung. Dikatakan bahwa kedua tim akan **sukses bersama atau gagal bersama**.
- Karena sangat erat, kedua tim sering bertemu untuk menyinkronkan jadwal dan pekerjaan yang saling bergantung, serta wajib menggunakan integrasi berkelanjutan (*Continuous Integration*) untuk menjaga keharmonisan integrasi mereka.
- Garis pemetaan tebal menunjukkan tingkat komitmen yang sangat tinggi yang dituntut. Hubungan ini sebaiknya dibatasi jangka waktunya agar tidak menguras energi tim secara berlebihan dalam jangka panjang.

#### 2. Shared Kernel (Inti Bersama)
Pola ini menggambarkan hubungan di mana dua atau lebih tim berbagi sebagian kecil model domain dan basis kode yang sama.
- Tim-tim tersebut harus sepakat tentang elemen model mana yang akan mereka bagi.
- *Shared Kernel* sering kali sangat sulit dirancang pada awalnya dan sulit dipertahankan, karena menuntut komunikasi terbuka yang konstan dan persetujuan bersama setiap kali ada perubahan kode. Namun, pola ini berguna jika seluruh pihak berkomitmen bahwa berbagi kernel kecil lebih baik daripada membuat duplikasi terpisah (*Separate Ways*).

#### 3. Customer-Supplier (Pelanggan - Pemasok)
Hubungan ini menggambarkan relasi antara dua *Bounded Contexts* dan tim masing-masing di mana **Pemasok berada di Upstream (U)** dan **Pelanggan berada di Downstream (D)**.
- Pihak Upstream memegang kendali karena merekalah yang menyediakan data/layanan yang dibutuhkan oleh Downstream.
- Pihak Downstream (Pelanggan) berdiskusi dan merencanakan kebutuhan fitur bersama Upstream (Pemasok), tetapi pada akhirnya pihak Upstream yang menentukan apa yang akan dikirimkan dan kapan waktu pengirimannya.
- Ini adalah hubungan yang sangat umum dan praktis antar-tim di dalam organisasi yang sama.

#### 4. Conformist (Konformis)
Hubungan Konformis terjadi ketika ada tim Upstream dan Downstream, tetapi tim Upstream **sama sekali tidak memiliki motivasi atau kewajiban untuk mendukung kebutuhan spesifik tim Downstream**.
- Tim Downstream tidak memiliki daya tawar untuk meminta perubahan skema dari Upstream.
- Karena tim Downstream tidak mampu atau tidak mau menanggung biaya pembuatan lapisan penerjemah bahasa, tim Downstream memilih untuk **tunduk dan menyesuaikan diri 100% (*conform*) dengan model data Upstream apa adanya**.
- Contoh: Pengembang aplikasi pihak ketiga yang harus patuh mutlak pada model API Amazon.com atau Google Maps API.

#### 5. Anticorruption Layer / ACL (Lapisan Antikorupsi)
**ACL adalah pola pemetaan konteks yang paling defensif dan paling aman.**
- Tim Downstream menciptakan lapisan penerjemah di antara *Ubiquitous Language* modelnya sendiri dan model Upstream.
- Lapisan ini mengisolasi model Downstream dari model Upstream dan menerjemahkan data di antara keduanya.
- **Tujuan Utama ACL:** Melindungi kemurnian model domain baru agar tidak terkontaminasi oleh struktur data yang buruk, aneh, atau kotor dari sistem luar / sistem warisan (*Big Ball of Mud*). Dengan ACL, Anda tidak dipaksa berbicara menggunakan bahasa kotor sistem legacy.

#### 6. Open Host Service (OHS) & Published Language (PL)
- **Open Host Service (OHS):** Mendefinisikan protokol atau antarmuka standar terbuka yang memberikan akses ke *Bounded Context* Anda sebagai sekumpulan layanan (API). Layanan OHS terdokumentasi dengan sangat baik dan mudah digunakan oleh siapa saja.
- **Published Language (PL):** Bahasa pertukaran informasi yang terdokumentasi dengan baik (seperti skema JSON, XML Schema, atau format serialisasi seperti Protobuf/Avro) yang memungkinkan konsumsi dan penerjemahan data secara mudah oleh banyak *Bounded Contexts* pemakai.

#### 7. Separate Ways (Jalan Sendiri)
Situasi di mana integrasi dengan *Bounded Context* lain tidak memberikan keuntungan yang sebanding dengan biaya integrasinya. Fungsionalitas yang dicari tidak sepenuhnya disediakan oleh sistem lain, sehingga tim memutuskan untuk membuat solusi tersendiri di dalam konteksnya dan melupakan integrasi.

#### 8. Big Ball of Mud (Bola Lumpur Raksasa)
Sistem monolitik kusut tanpa batas yang harus dihindari sebisa mungkin. Jika Anda terpaksa harus mengambil data dari sebuah *Big Ball of Mud*, **WAJIB pasang Anticorruption Layer (ACL)** di depan sistem Anda agar kebusukan model lama tidak menular ke model baru Anda.

---

### Tiga Mekanisme Integrasi Teknis Utama

Bagaimana secara fisik dua *Bounded Contexts* saling bertukar data?

#### 1. RPC dengan SOAP (Remote Procedure Calls)
- Menggunakan protokol SOAP berbasis XML di atas HTTP.
- Memperlakukan pemanggilan service jarak jauh seperti pemanggilan fungsi lokal biasa.
- **Kelemahan:** Mengakibatkan keterikatan yang sangat kuat (*tight coupling*). Jika jaringan lambat atau server penyedia mengalami gangguan, aplikasi pemanggil akan langsung macet (*blocked*) dan gagal total.

#### 2. RESTful HTTP
- Berfokus pada pertukaran sumber daya (*resources*) menggunakan operasi standar HTTP: `GET`, `POST`, `PUT`, `DELETE`.
- Sangat populer dan terbukti andal untuk komputasi terdistribusi.
- **Peringatan Desain REST:** Hindari merancang endpoint REST yang secara langsung mengekspos Agregat internal model domain Anda! Jika Agregat berubah, API Anda akan rusak. Rancanglah resource REST secara sintetis sesuai use-case yang dibutuhkan klien.

#### 3. Asynchronous Messaging & Domain Events (Pesan Asinkron)
- **Bentuk integrasi paling tangguh dan sangat direkomendasikan dalam DDD.**
- Satu *Bounded Context* menerbitkan **Domain Event**, dan *Bounded Context* lain berlangganan (*subscribe*) event tersebut melalui sistem pesan (*message broker / queue*).
- Menghilangkan keterikatan waktu (*temporal coupling*). Sistem pemanggil tidak perlu menunggu atau memblokir eksekusi pengguna.

---

### Pola Pengiriman & Konsistensi Pesan:

1. **At-Least-Once Delivery (Pengiriman Minimal Sekali):**  
   Pola di mana mekanisme antrean pesan menjamin bahwa pesan pasti terkirim minimal satu kali, meskipun ada kemungkinan terjadi pengiriman duplikat akibat gangguan jaringan sementara.
2. **Idempotent Receiver (Penerima Idempoten):**  
   Pihak penerima pesan dirancang sedemikian rupa sehingga jika pesan yang sama diterima lebih dari sekali, operasi yang dieksekusi menghasilkan status yang sama aman tanpa menimbulkan duplikasi transaksi bisnis (misalnya mendeteksi event ID unik yang sudah pernah diproses).
3. **Causal Consistency (Konsistensi Kausalitas):**  
   Menjamin bahwa peristiwa yang saling menyebabkan satu sama lain diproses dalam urutan kronologis yang benar oleh seluruh subsistem.

---

### Contoh Alur Integrasi Domain Event: Penerbitan Polis Asuransi

1. Komponen `Policy` di dalam *Underwriting Context* berhasil disetujui dan diterbitkan.
2. *Underwriting Context* menerbitkan Domain Event bernama **`PolicyIssued`** yang berisi atribut penting: `policyId`, tanggal terbit, dan data ringkas.
3. Event `PolicyIssued` disimpan ke basis data (*Event Store*) dalam transaksi yang sama dan dikirimkan ke mekanisme messaging.
4. *Inspections Context* dan *Claims Context* menerima event `PolicyIssued` tersebut dan membuat rekaman `Policy` lokal versi mereka masing-masing dengan menyimpan referensi `issuedPolicyId`.

#### Pertimbangan Pengayaan Data vs Kueri Ulang (*Enrichment vs. Query-Back*):
- **Enrichment (Pengayaan Data Event):** Mengisi Domain Event dengan data selengkap mungkin agar penerima tidak perlu bertanya balik ke konteks asal. Sangat baik untuk otonomi sistem, namun harus hati-hati agar tidak membocorkan data sensitif.
- **Query-Back (Kueri Balik):** Menjaga Domain Event tetap tipis (hanya ID dan info penting). Jika penerima membutuhkan rincian lebih lanjut, penerima melakukan panggilan REST API `GET /policies/{issuedPolicyId}` kembali ke *Underwriting Context*.
