Kontrak Data

Backward Compatibility: Mengubah Kontrak Data Tanpa Mematahkan Konsumen Lama

Membedakan perubahan kompatibel dan breaking pada field, enum, perilaku, error, serta merancang migrasi kontrak yang aman.

Backward compatibility berarti konsumen lama tetap bekerja secara benar setelah provider berubah. “Tidak crash” belum cukup: consumer dapat terus berjalan tetapi menafsirkan nilai secara salah. Review perlu mencakup schema, semantik, urutan, error, dan timing proses.

Tujuan perubahan Tambahkan secara toleran, jangan mengubah makna diam-diam, uji consumer lama, dan gunakan versi baru ketika kompatibilitas tidak dapat dipertahankan dengan jujur.

Apa arti kompatibel bagi provider dan consumer?

Provider backward-compatible dapat melayani consumer lama sesuai kontraknya. Consumer forward-tolerant dapat mengabaikan field atau enum baru dengan perilaku aman. Kedua sisi tetap memiliki batas. Consumer yang menolak field tambahan membuat evolusi sulit, sedangkan consumer yang mengubah nilai tidak dikenal menjadi default dapat menyembunyikan masalah.

Tetapkan kontrak eksplisit sebagaimana dijelaskan pada kontrak data sebelum payload. Compatibility adalah hubungan antara dua versi dan perilaku consumer, bukan properti schema tunggal.

Perubahan field mana yang aman atau breaking?

PerubahanBiasanyaSyarat
Tambah response field opsionalKompatibelConsumer mengabaikan yang tidak dikenal
Tambah required request fieldBreakingConsumer lama tidak mengirimnya
Perlebar rentang angkaBisa breakingConsumer mungkin overflow
Tambah enum responseBisa breakingConsumer harus punya unknown handling
Ubah arti nullBreaking semantikSchema mungkin tetap sama

Mengapa perilaku juga bagian kontrak?

Perubahan dari hasil final menjadi accepted-asynchronous dapat mematahkan consumer yang langsung mengirim barang. Mengubah urutan default, pagination, pembulatan, idempotensi, atau status error juga memengaruhi keputusan. Dokumentasi harus menyebut jaminan, bukan hanya contoh JSON.

Gunakan contract testing dengan assertion perilaku. Test schema tidak akan menemukan bahwa total kini dihitung setelah diskon dengan aturan pembulatan berbeda.

Pola apa yang membantu evolusi aman?

Expand-and-contract menambah field baru lebih dahulu, membuat provider mengisi lama dan baru, memigrasikan consumer, lalu menghapus field lama setelah bukti penggunaan nol. Tolerant reader menerima tambahan yang tidak memengaruhi keputusan, tetapi menolak nilai kritis yang tidak dipahami. Default hanya digunakan bila maknanya disetujui.

  1. Expand.

    Tambahkan bentuk baru tanpa menghapus lama.

  2. Migrate.

    Uji dan pindahkan consumer bertahap.

  3. Observe.

    Pastikan jalur lama tidak digunakan.

  4. Contract.

    Hapus setelah tenggat dan approval.

Bagaimana menangani data tertunda dan arsip?

Message, file, atau event lama dapat muncul setelah provider berubah. Simpan versi pada data bila perlu, pertahankan reader lama selama masa yang didefinisikan, atau migrasikan arsip. Jangan menganggap trafik live nol berarti tidak ada replay, backup restore, atau proses offline yang memakai kontrak lama.

Hubungkan dengan API versioning dan inventaris consumer. Keputusan retirement harus mempertimbangkan retensi bisnis, bukan hanya kalender proyek.

Checklist apa yang digunakan sebelum rilis?

  • Perubahan schema dan semantik diklasifikasikan.
  • Consumer lama diuji dengan provider baru.
  • Enum, null, precision, error, dan timing tercakup.
  • Data tertunda serta replay masuk dalam scope.
  • Telemetry adopsi dan rollback tersedia.
  • Pemilik consumer menyetujui tenggat penghentian.

NitroNet dapat dievaluasi untuk membuat transformasi dan jalur migrasi terlihat, tetapi artikel ini tidak mengungkap implementasi produk. Gunakan komunikasi perubahan schema dan readiness review agar compatibility menjadi bukti, bukan harapan.

Red-team perubahan yang tampak aman

Sebelum rilis, minta reviewer berperan sebagai consumer lama yang tidak mengetahui niat provider. Beri hanya kontrak versi lama dan perubahan baru. Tujuannya menemukan asumsi tersembunyi yang tidak terlihat dari diff schema.

  • Tambahkan enum response baru dan lihat apakah consumer menolak, crash, atau memakai default berbahaya.
  • Perlebar angka melampaui integer consumer serta gunakan decimal dengan precision yang berbeda.
  • Ubah field optional menjadi selalu hadir null dan periksa perbedaan makna pada parser lama.
  • Tambahkan field ke object yang consumer deserialisasikan dengan mode strict unknown-property.
  • Ubah urutan default serta pagination tanpa mengubah nama field atau tipe response.
  • Percepat response menjadi accepted sebelum efek selesai dan lihat tindakan bisnis consumer.
  • Replay payload versi lama setelah migrasi untuk menguji reader serta data tertunda.
  • Latih rollback ketika sebagian consumer sudah menulis data dalam bentuk baru.

Jika consumer lama tidak dapat bertindak benar, perubahan itu breaking meskipun schema validator lulus. Pilih expand-and-contract atau versi baru, lalu pantau adopsi. Jangan memaksa nilai baru ke default lama hanya untuk mempertahankan bentuk; compatibility harus mempertahankan makna, bukan sekadar menghindari error parsing.

Buat matriks kompatibilitas sebelum rilis: producer lama ke consumer baru, producer baru ke consumer lama, pesan tertunda, replay, dan data yang belum memiliki field tambahan. Sertakan hasil bisnis yang diharapkan pada setiap kombinasi. Pengujian ini menemukan masalah yang luput dari pemeriksaan schema, misalnya nilai enum baru berhasil dibaca tetapi diperlakukan sebagai status yang salah. Hapus dukungan lama hanya setelah bukti penggunaan menunjukkan consumer terkait telah berpindah dan periode data tertunda sudah terlewati.

Bawa konsep ke kasus nyata

Sedang merancang integrasi lintas-sistem?

Petakan satu alur nyata bersama tim NitroNet untuk melihat posisi agent, Core, workflow, dan batas transaksinya.

Bahas arsitektur AndaKembali ke blog
Chat WhatsApp