Kontrak data tidak diam: API menambah properti baru, sementara klien lama masih mengirim payload versi sebelumnya. System.Text.Json menyediakan aturan versioning yang meminimalkan rusaknya komunikasi. Ketika JSON berisi anggota yang tidak dikenal, anggota tersebut diabaikan; ketika JSON kekurangan properti, properti class memakai nilai default; dan kata kunci required memaksa deserialisasi gagal bila properti wajib tidak hadir.

Contoh Tiga Skenario Versi #

Class ProdukVersi mewakili skema baru dengan properti Aktif, sedangkan KartuProduk menandai Gudang sebagai required:

csharp
string jsonLama = """{"Nama":"Kopi Gayo"}""";

ProdukVersi lama = JsonSerializer.Deserialize<ProdukVersi>(jsonLama);
Console.WriteLine($"JSON lama -> Nama='{lama.Nama}', Stok={lama.Stok}, Aktif={lama.Aktif}");

string jsonBaru = """{"Nama":"Kopi Gayo","Stok":12,"Aktif":true,"Harga":45000}""";
ProdukVersi baru = JsonSerializer.Deserialize<ProdukVersi>(jsonBaru);
Console.WriteLine($"JSON baru -> Nama='{baru.Nama}' (properti Harga diabaikan)");

try
{
    JsonSerializer.Deserialize<KartuProduk>(jsonLama);
}
catch (JsonException e)
{
    Console.WriteLine($"JsonException: {e.Message}");
}

Output yang Dihasilkan:

text
JSON lama -> Nama='Kopi Gayo', Stok=0, Aktif=True
JSON baru -> Nama='Kopi Gayo' (properti Harga diabaikan)
JsonException: JSON deserialization for type 'Verify6d.KartuProduk' was missing required properties including: 'Gudang'.

Mari kita bedah ketiga hasil:

  1. JSON lama: properti Stok dan Aktif tidak ada di JSON; deserializer mengisi Stok dengan 0 dan membiarkan Aktif memakai nilai awal true dari initializer class.
  2. JSON baru: anggota Harga tidak dikenal oleh ProdukVersi, sehingga diabaikan tanpa galat; klien lama tetap berjalan meski server menambah properti.
  3. required Gudang: deserialisasi melempar JsonException dengan pesan yang menyebut tipe lengkap dan properti yang hilang; pola ini cocok untuk field yang tidak boleh diam-diam kosong seperti kunci referensi.

Kedua mekanisme saling melengkapi saat skema terus bergerak. Properti baru ditambahkan tanpa penanda apa pun sehingga klien lama tetap membaca payload baru; properti yang wajib ditandai required agar klien lama gagal cepat dengan pesan jelas, bukan berjalan dengan data setengah isi. Kebalikannya juga berlaku: payload lama yang membawa anggota tak dikenal tidak boleh membuat versi baru gagal, dan aturan pengabaian default menjamin hal itu.