API Versioning Saat Vendor Tidak Mau Versioning Sama Sekali

API Versioning Saat Vendor Tidak Mau Versioning Sama Sekali
Malam 12 Januari 2023, Tweetbot, Twitterrific, Echofon, Fenix, Twitpane, Feather, dan Talon berhenti berfungsi bersamaan. Pengguna tidak bisa login. Semua panggilan API gagal, dan aplikasi-aplikasi itu tampil "Suspended" di developer portal Twitter — tanpa peringatan sebelumnya.
Developer menebak-nebak penyebabnya malam itu juga. Seminggu kemudian, developer-agreement baru menjadikan larangan itu permanen.
Tidak satu pun tim itu men-ship kode rusak. Integrasi mereka baik-baik saja, sampai vendor mengubah aturan main di bawahnya — tanpa deprecation notice, tanpa versi untuk rollback. Itulah mode kegagalan yang dibahas artikel ini: bergantung pada API yang dikendalikan orang lain, yang tidak merasa wajib melakukan versioning.
Bayangkan API vendor seperti jalan tol yang bisa berubah rute kapan saja tanpa rambu. Sebagian besar integrasi vendor berada di antara dua ujung: "disiplin seperti Stripe" dan "tanpa peringatan seperti Twitter 2023." Asumsikan ujung yang lebih buruk. Roadmap vendor mana pun tidak bisa dinegosiasikan begitu saja.
Seperti apa versioning yang baik
URL path atau query-param versioning (/v2/orders) paling umum dan paling mudah dipahami. Custom header versioning membuat URL tetap stabil, tapi mudah terlupakan kalau client library tidak menyetel header-nya. Media-type versioning (Accept: application/vnd.vendor.v2+json) adalah jawaban REST paling benar — dan paling jarang dipakai vendor.
Stripe mem-pin setiap akun ke versi bertanggal, misalnya 2026-07-29, sejak panggilan API pertama. Panggilan berikutnya memakai versi yang sama, kecuali di-override lewat header Stripe-Version. Upgrade bisa di-dry-run dari staging lebih dulu. (docs, upgrade guide)
GitHub merekomendasikan header X-GitHub-Api-Version di setiap request. Kalau header dilewati, GitHub default ke versi tetap, bukan "terbaru." Setiap versi didukung minimal 24 bulan lewat header peringatan Deprecation/Sunset, lalu mengembalikan 410 Gone begitu pensiun. (docs)
Shopify merilis versi bertanggal tiap kuartal, dengan jaminan 12 bulan dukungan dan 9 bulan overlap. Request yang mengarah ke versi pensiun tetap dilayani, bukan gagal keras: 2026-10 yang sudah pensiun otomatis dilayani sebagai 2027-01. (docs)
Sebagian besar vendor yang benar-benar dipakai untuk integrasi — payment aggregator regional, SDK hardware, channel manager — tidak punya satu pun dari ini. Cuma ada satu versi, disebut "API-nya," dan ia berubah kapan pun roadmap vendor bilang begitu.
Pattern 1: tolerant reader
Pattern Tolerant Reader dari Martin Fowler menerapkan Postel's Law ke parsing. Ambil hanya field yang dibutuhkan dari sebuah response. Abaikan sisanya, dan beri default untuk yang hilang — jangan lempar error.
Contoh Fowler memakai XPath: query //order, bukan path absolut yang kaku. Kalau vendor menyisipkan elemen wrapper, integrasinya tidak ikut rusak. Diterapkan ke JSON: baca response.customer.email langsung, jangan validasi seluruh object sebagai struct ketat, dan jangan pernah mengasumsikan urutan field.
Fowler menautkan tulisan Ian Cartwright yang menandai satu hal penting: validasi schema yang ketat memberi "rasa aman yang palsu." Schema yang mem-pin setiap field menolak perubahan aman sama kerasnya dengan perubahan yang benar-benar breaking — ia tidak bisa membedakan keduanya. Separuh lain dari pattern ini: sentralkan parsing di satu tempat, biasanya sebuah DTO, sehingga cuma satu titik di codebase yang tahu bentuk response asli vendor.
Pattern 2: contract test sebagai tripwire
Pattern Consumer-Driven Contracts dari Fowler dibangun untuk tim internal. Tiap consumer menulis assertion yang menjelaskan field dan perilaku apa saja yang ia andalkan. Provider menjalankan semua contract itu terhadap build-nya sendiri, untuk mendapat feedback cepat sebelum mengirim perubahan breaking.
Menyisipkan contract ke pipeline vendor tidak mungkin. Tapi contract itu tetap bisa ditulis dan dijalankan sendiri terhadap sandbox mereka secara terjadwal — sebuah tripwire, bukan merge gate. Assert field, tipe data, dan status code persis yang diandalkan integrasinya, lalu jalankan pengecekan itu tiap malam. Saat sebuah field diam-diam hilang atau berubah tipe, test itu gagal berjam-jam sebelum pelanggan menyadarinya.
Pattern 3: anti-corruption layer
Beri bentuk data vendor tepat satu pintu masuk ke sistem.
Tanpa batas ini, vendor yang mengganti nama customer_email menjadi contact_email memaksa grep manual ke setiap service yang pernah menyentuh order. Dengan batas ini, penggantian nama itu cuma perbaikan satu file di dalam layer. Semua yang di hilirnya tidak pernah tahu nama field-nya berubah — logika parsing tinggal di satu batas ini saja.
Pattern 4: pin dan monitor
Kalau vendor mendukungnya, pin ke versi tertentu — jangan mengambang di apa pun yang dikembalikan API hari ini. Vendor kelas menengah makin sering meniru model versi bertanggal Stripe, minus disiplinnya. Pinning mengubah kerusakan tak disengaja menjadi upgrade yang dijadwalkan sendiri.
Kalau pinning tidak tersedia — dan itu berlaku untuk sebagian besar vendor — monitoring adalah yang tersisa. Jalankan contract test dari pattern 2 terhadap production juga, bukan cuma sandbox. Keduanya bisa saling menyimpang, atau sandbox-nya tidak pernah disentuh sama sekali. Diff terjadwal antara bentuk response hari ini dan kemarin menangkap penyimpangan dalam hitungan jam, sebelum sampai ke pelanggan sebagai fitur rusak.
Tuliskan kewajiban notifikasi perubahan di kontrak
Pertahanan teknis baru separuh urusan. Separuh lainnya bersifat kontraktual, dan tetap layak dilakukan meski sebagian besar vendor tidak akan mencapai disiplin setara Stripe atau GitHub.
Microsoft REST API Guidelines mendefinisikan breaking change secara umum: apa pun yang memengaruhi contract atau backward compatibility. Tiap tim service lalu wajib menulis daftar konkretnya sendiri — Azure menganggap field baru di response JSON sebagai breaking, Office 365 tidak. Pinjam model itu: minta vendor memberi definisi spesifik, bukan janji yang kabur.
Kebijakan breaking-change LinkedIn lebih rinci dan lebih mudah ditiru langsung. Breaking change, seperti menghapus field, menambah parameter wajib tanpa default, atau DELETE yang berubah dari soft-delete menjadi hard-delete, mendapat notifikasi email lebih dulu. Perubahan non-breaking, seperti field opsional baru, langsung dirilis tanpa notifikasi.
LinkedIn juga berhak melewati notifikasi untuk perbaikan bug kritis, hukum, keamanan, atau privasi. Baca pengecualian ini baik-baik — justru itulah jenis perubahan yang biasanya merusak integrasi.
Minta tiga hal saat negosiasi: definisi tertulis soal "breaking" yang spesifik untuk API mereka, periode notifikasi minimum, dan kanal notifikasi yang nyata. Kanal itu berarti email atau webhook, bukan halaman changelog yang tidak pernah dicek siapa pun. Sebagian besar vendor akan setuju, karena berjanji itu murah. Itulah sebabnya empat pattern teknis di atas tetap perlu dibangun, terlepas dari isi kontrak.
Yang harus diminta, dan yang harus tetap dibangun
Sebelum tanda tangan: definisi breaking-change tertulis, periode notifikasi minimum, kanal notifikasi yang nyata, dan versi yang bisa di-pin kalau mereka menawarkannya.
Bangun terlepas dari apa yang mereka janjikan: tolerant reader sebagai satu-satunya bagian yang menyentuh response mentah vendor, dan contract test terjadwal terhadap sandbox dan production. Tambahkan anti-corruption layer sebagai satu titik translasi, dan monitoring yang seharusnya menangkap kejadian 12 Januari 2023 dalam hitungan jam, bukan dari keluhan pengguna. Janji vendor cuma peredam risiko. Pertahanan sendiri yang benar-benar menyelamatkan saat janji itu tidak ditepati.
Kalau integrasinya mencakup banyak jenis hardware atau protokol, bukan cuma satu REST API, ide batas-translasi yang sama muncul lagi di normalisasi perangkat IoT multi-protokol. Masalah berbeda, solusi yang sama.
Artikel Terkait
Mau bangun hal serupa?
Jasa Pengembangan Backend IoT & Integrasi Multi-Protokol
Backend yang menyerap telemetri perangkat lintas MQTT, WebSocket, Modbus, dan BLE, lalu menyatukannya jadi dashboard real-time yang andal.
Lihat cara saya bisa bantu