Praktik terbaik versi API, demi kepentingan pemanggil
6 menit baca
Versi API adalah praktik menjaga kontrak lama tetap berfungsi setelah Anda mengubahnya, sehingga pemanggil bisa maju sesuai jadwal mereka sendiri alih-alih jadwal Anda. Kalimat itu berisi dua keputusan yang penting: apa yang terhitung sebagai mengubah kontraknya, dan berapa lama yang lama tetap berfungsi. Di mana nomor versi berada, yang menjadi topik kebanyakan perdebatan versi, adalah yang paling tidak penting dari ketiganya dan paling mudah dibenarkan.
Kapan sebuah API seharusnya diversikan?
Versikan API hanya ketika sebuah perubahan akan merusak pemanggil yang benar. Perubahan aditif, field baru, endpoint baru, parameter opsional baru, tidak membutuhkan versi; pemanggil yang ditulis terhadap kontrak lama tetap berfungsi dan kemampuan baru itu ada begitu saja. Sebuah breaking change membutuhkannya, karena alternatifnya adalah pemanggil mengetahuinya dari error. Memversikan setiap rilis, termasuk yang aditif, mengajarkan pemanggil bahwa versi adalah kebisingan, dan mereka berhenti membaca pemberitahuan yang penting.
Tes praktisnya sama dengan artikel tentang breaking change: jika pemanggil yang hanya mengandalkan perilaku terdokumentasi harus mengubah sesuatu untuk tetap berfungsi, perubahan itu membutuhkan versi. Jika tidak, rilis di bawah versi saat ini dan tulis entri changelog.
Skema versi API mana yang seharusnya digunakan?
Gunakan skema yang paling mudah dilihat dan ditetapkan pemanggil Anda, yang untuk kebanyakan API publik adalah versi di jalur URL atau header versi bertanggal. Empat skema umum berbeda lebih sedikit dalam kemampuan daripada dalam apa yang mereka minta dari pemanggil, dan itu dasar yang tepat untuk memilih.
| Skema | Contoh | Yang harus dilakukan pemanggil | Siapa yang menggunakan |
|---|---|---|---|
| Jalur URL | /v2/invoices | Mengubah URL saat bermigrasi | Kebanyakan API REST publik |
| Header versi | X-GitHub-Api-Version: 2022-11-28 | Mengirim header, atau menerima default | GitHub |
| Versi akun bertanggal | Stripe-Version: 2026-08-26 | Menetapkan tanggal per permintaan atau per akun | Stripe |
| Parameter query | /invoices?version=2 | Menambahkan parameter | API lama; sekarang jarang dipilih |
| Media type | Accept: application/vnd.example.v2+json | Bernegosiasi jenis konten | Purist; sedikit pemanggil bisa mengelola |
Jalur URL paling terlihat dan paling tidak fleksibel. Setiap pemanggil bisa melihat versi mereka dengan membaca baris log, dan lompatan versi adalah cari-dan-ganti. Biayanya: seluruh permukaan bergerak sekaligus, Anda tidak bisa mengubah kontrak satu endpoint tanpa mencetak versi baru untuk semuanya, jadi versi jalur cenderung jarang dan besar.
Header versi menjaga URL tetap stabil dan membiarkan server memilih default untuk pemanggil
yang tidak mengirim apa pun, seperti cara kerja
versi API REST GitHub:
versi bernama tanggal dalam X-GitHub-Api-Version, dengan versi yang didukung tertua sebagai
default agar pemanggil tanpa versi tidak rusak. Biayanya: versinya tidak terlihat dalam URL dan
mudah dilupakan dalam klien baru.
Versi akun bertanggal adalah skema header ditambah satu tambahan: versinya disimpan terhadap
akun, sehingga setiap permintaan mendapatkannya tanpa mengirim apa pun.
Versi API Stripe menetapkan setiap akun ke versi saat
dibuat dan membiarkan permintaan menimpanya dengan Stripe-Version. Ini skema paling ramah
pemanggil dan paling banyak pekerjaan untuk dijalankan, karena server harus menerjemahkan antara
setiap versi yang didukung dan yang saat ini. Skema Stripe adalah contoh paling terkenal dari
pendekatan tanggal, dan cara Stripe memberi versi pada API-nya
membahasnya langkah demi langkah.
Parameter query dan media type keduanya berfungsi dan keduanya gagal dalam tes visibilitas dengan cara berbeda: parameter query mudah hilang saat membangun URL, dan versi media type tidak terlihat oleh hampir semua alat yang digunakan pemanggil untuk debug.
Bagaimana versi API dilakukan dalam praktik?
Dalam praktik versi adalah kumpulan perilaku bernama, dan server memetakan setiap permintaan ke salah satunya. Langkah-langkahnya sama apa pun skema yang membawa namanya.
- Namai versi berdasarkan tanggal atau bilangan bulat, bukan versi semantik. API web bukan
paket. Pemanggil tidak bisa menetapkan versi minor dari URL, jadi
v2atau2026-08-26mengatakan semua yang dibutuhkan pemanggil, dan versi semantik menyiratkan janji kompatibilitas yang tidak bisa dipenuhi skema tersebut. - Jaga versinya di luar jalur kode yang tidak peduli. Versi seharusnya memilih lapisan terjemahan di tepi, bukan mencabangkan logika bisnis. Dua salinan penuh dari kode basis adalah bagaimana versi berakhir tidak terpelihara.
- Beri setiap versi default dan dokumen. Pemanggil yang tidak mengirim versi mendapat yang paling lama didukung, tidak pernah yang terbaru, sehingga klien yang tidak ditetapkan tidak rusak pada hari rilis. Setiap versi punya halaman yang mengatakan apa yang berubah dari yang sebelumnya.
- Tetapkan jendela dukungan dan terbitkan. Panduan versioning Google, AIP-185, meminta masa transisi yang wajar dan dikomunikasikan dengan baik, serta merekomendasikan 180 hari bahkan untuk fungsionalitas beta. Pilih jendela, tulis, dan terapkan tanpa negosiasi ulang per versi.
- Pensiunkan versi seperti Anda mempensiunkan endpoint. Versi yang melewati jendelanya
mendapat perlakuan yang sama dengan API yang di-deprecate: sebuah
pengumuman, header
Sunset(RFC 8594) di setiap respons, pengingat di tengah jalan kepada pemanggil yang tersisa, dan tanggal penghapusan yang dipegang teguh.
Apa itu v1 dan v2 dalam API REST?
v1 dan v2 adalah nama untuk dua kontrak yang didukung server yang sama pada saat bersamaan.
v2 ada karena sesuatu di v1 tidak bisa diubah tanpa merusak pemanggilnya, jadi perubahannya
masuk ke kontrak baru dan yang lama tetap berfungsi. Angka-angka itu tidak menyiratkan bahwa v2
lengkap atau v1 mati; keduanya hanya benar jika dokumentasi mengatakannya. v3 yang muncul
setiap kuartal adalah tanda bahwa perubahan aditif sedang diversikan, atau bahwa kontraknya tidak
pernah dirancang untuk menyerap perubahan. gRPC
menyelesaikan masalah yang sama secara berbeda: perubahan API gRPC dan Protobuf
membahas versi lewat nama paket dalam berkas .proto alih-alih jalur URL, dan format wire di
mana mengganti nama field gratis tapi menomorinya ulang adalah breaking change yang tidak akan
dikenali pemanggil REST mana pun sebagai berisiko.
Apa yang harus diumumkan perubahan versi?
Perubahan versi harus mengumumkan apa yang rusak, siapa yang terdampak, cara bermigrasi, dan berapa lama versi sebelumnya tetap berfungsi. Entrinya punya bentuk yang sama dengan entri breaking change lainnya, ditambah satu baris menyatakan jendela dukungan. Berikut satu untuk API yang diversikan dengan header:
Versi API 2026-11-01 tersedia. Versi 2025-06-15 didukung hingga 1 November 2027. Baru di 2026-11-01:
GET /invoicesmengembalikanamountdalam unit terkecil sebagai bilangan bulat alih-alih string desimal, dan field yang di-deprecatecustomer_namedihapus demi objekcustomer. Memengaruhi pemanggil di 2025-06-15 yang menguraiamountsebagai string, yang merupakan default untuk klien tidak ditetapkan yang dibuat sebelum Juni 2025. Migrasi: uraikanamountsebagai bilangan bulat dan baca namanya daricustomer.name. TetapkanX-Api-Version: 2026-11-01saat Anda siap. Tidak ada yang berubah untuk pemanggil yang tidak menetapkan versi.
Kalimat terakhir itu yang memungkinkan kebanyakan pembaca berhenti membaca, dan itu milik setiap pengumuman versi. Halaman contoh changelog menyertakan entri dari API yang memversikan seperti ini, dan perbedaan antara yang baik dan sisanya sebagian besar ada di kalimat terakhir itu.
Siapa yang diberi tahu ketika versi berubah?
Semua orang di versi lama, secara individu, dan changelog untuk semua orang lainnya. Perubahan versi adalah satu-satunya kasus di mana “kami memposting tentang itu” dijamin akan melewatkan tepat pemanggil yang penting: mereka yang menetapkan versi dua tahun lalu dan belum membaca catatan rilis sejak itu. Data penggunaan menjawab siapa mereka; pemberitahuannya harus mencapai mereka di mana kode mereka berada, dalam header respons dan dalam pesan kepada pemilik akun.
Dalam lingkaran yang kami jalankan, entri yang mengumumkan versi disusun dari pull request yang merilisnya, ditinjau oleh seseorang, dan diterbitkan di feed dan widget, tempat klien berversi bisa membacanya sebagai JSON. Siapa pun yang masukan widget-nya meminta perubahan itu, atau melaporkan bug yang diselesaikannya, dan menjadi issue GitHub yang ditutup oleh pull request, diberi tahu di issue tersebut segera setelah entrinya live. Mekanismenya sama dengan entri mana pun; lompatan versi hanyalah entri dengan taruhan tertinggi.
FAQ
Haruskah setiap perubahan API mendapat versi baru? Tidak. Hanya breaking change. Perubahan aditif dirilis di bawah versi saat ini dengan entri changelog. Memversikan perubahan aditif melatih pemanggil untuk mengabaikan versi.
Apakah versi URL lebih baik daripada versi header? Versi URL lebih mudah dilihat pemanggil dan lebih sulit bagi Anda untuk berkembang sedikit demi sedikit; versi header sebaliknya. Untuk API publik dengan banyak klien kecil, versi URL gagal lebih sedikit. Untuk API besar dengan lapisan terjemahan, versi bertanggal berbasis header berskala lebih baik.
Berapa banyak versi yang seharusnya didukung sekaligus? Sesedikit yang diizinkan jendela dukungan Anda, dan tidak pernah jumlah tak terbatas. Dua atau tiga versi bersamaan itu normal; lebih dari itu biasanya berarti versi tidak dipensiunkan.
Apa yang seharusnya diterima permintaan tanpa versi? Versi yang paling lama didukung, sehingga klien yang ada dan tidak ditetapkan tetap berfungsi, dengan header respons yang memberi tahu mereka versi mana yang mereka terima.
Klaim teknis dalam artikel ini belum ditinjau secara independen. Jika ada yang keliru, beri tahu kami dan kami akan memperbaikinya.