Perubahan API

Cara men-deprecate API tanpa kehilangan developer

6 menit baca

Men-deprecate API berarti mengumumkan bahwa sesuatu masih berfungsi hari ini dan akan berhenti berfungsi pada tanggal yang dinyatakan, lalu menepati kedua bagian janji itu. Kebanyakan deprecation gagal di bagian kedua: tanggalnya bergeser diam-diam, atau tiba dan pemanggil yang tidak pernah melihat pemberitahuan mengetahuinya dari sebuah error. Deprecation selesai ketika setiap pemanggil yang terdampak sudah bermigrasi atau diberi tahu, secara individu, bahwa mereka belum.

Apa itu deprecation API?

Deprecation adalah periode antara mengumumkan bahwa endpoint, field atau versi akan menghilang dan benar-benar menghapusnya. Selama periode itu perilaku lama tetap berfungsi, dokumentasi mengatakan itu akan pergi, dan setiap respons membawa peringatan yang bisa dibaca mesin. Penghapusan adalah peristiwa terpisah, lebih belakangan, sering disebut sunset. Keduanya tercampur, dan pencampuran itu tempat kerusakan terjadi: “deprecated” mulai berarti “mungkin sudah hilang”, dan pemanggil berhenti mempercayai kedua kata itu.

IstilahArtiYang bisa diandalkan pemanggil
DeprecatedDiumumkan akan hilang, masih berfungsiPerilaku penuh sampai tanggal sunset
SunsetTanggal berhentinya berfungsiTidak ada apa pun setelah tanggal ini
Retired / dihapusHilang; permintaan gagalError, idealnya yang menyebutkan penggantinya
LegacyTidak jelas. Hindari kata iniTidak ada apa pun, yang menjadi masalahnya

Berapa lama periode deprecation seharusnya?

Cukup lama bagi pemanggil untuk mengetahuinya dan melakukan pekerjaan, diukur dari saat pemberitahuan mencapai mereka, bukan dari saat Anda menulisnya. Sembilan puluh hari adalah batas bawah umum untuk API web publik. Dua belas bulan itu normal untuk apa pun yang tertanam dalam perangkat lunak yang diinstal pengguna akhir, karena perbaikannya juga harus melalui proses rilis mereka. Panduan versioning Google, AIP-185, meminta masa transisi yang wajar dan merekomendasikan 180 hari bahkan sebelum menghapus fungsionalitas beta, dan Kubernetes mendokumentasikan kebijakan deprecation-nya dalam jumlah rilis alih-alih bulan, yang merupakan satuan yang tepat ketika pemanggil Anda memperbarui berdasarkan versi.

Pilih satu periode, tuliskan sebagai kebijakan, dan berhenti memutuskannya per perubahan. Kebijakan yang diterbitkan mengubah setiap deprecation dari negosiasi menjadi penerapan aturan.

Menuliskan kebijakan deprecation mencakup awal jendela waktu; mengakhiri versi API membahas pemberitahuan terpisah yang dibutuhkan di akhir, saat periode itu benar-benar habis dan versi berhenti bekerja.

Jadwal deprecation

Empat tanggal, diumumkan bersama pada hari pertama. Masing-masing adalah entri changelog terpisah saat tiba, jadi ceritanya diceritakan empat kali kepada siapa pun yang hanya membaca changelog.

  1. Umumkan. Entri menyatakan apa yang di-deprecate, mengapa, apa penggantinya, dan tanggal sunset. Dokumentasi untuk hal lama mendapat banner yang menautkan ke migrasi. Respons mendapat header yang dijelaskan di bawah.
  2. Ingatkan, di tengah jalan. Entri kedua, dan pesan langsung ke setiap pemanggil yang masih menggunakan perilaku lama. Ini langkah yang membutuhkan data penggunaan: jika Anda tidak bisa mendaftar siapa yang masih memanggil endpoint yang di-deprecate, Anda tidak bisa melakukannya, dan layak diperbaiki sebelum deprecation berikutnya.
  3. Brownout, sesaat sebelum tanggalnya. Kembalikan error untuk perilaku lama selama jendela singkat, satu jam atau satu hari, lalu pulihkan. Pemanggil yang melewatkan setiap pemberitahuan mengetahuinya sekarang, selagi masih ada waktu. GitHub menggunakan brownout terjadwal sebelum mempensiunkan autentikasi kata sandi untuk API, dan ini langkah tunggal paling efektif dalam daftar ini.
  4. Sunset. Hapus. Error yang menggantikannya menyebutkan penggantinya dan menautkan panduan migrasi. Pertahankan error itu di tempatnya untuk waktu yang lama; 404 tidak memberi tahu pemanggil apa-apa.

Apa yang harus dikatakan pemberitahuan deprecation?

Pemberitahuan deprecation mengatakan apa yang akan hilang, kapan berhenti, apa yang digunakan sebagai gantinya, dan siapa yang terdampak. Berikut bentuknya, terisi:

GET /v1/reports/daily di-deprecate dan berhenti berfungsi pada 1 Maret 2027. Digantikan oleh GET /v2/reports?granularity=day, yang mengembalikan data yang sama dengan skema stabil dan penomoran halaman. Memengaruhi 214 integrasi yang memanggil endpoint v1 dalam 30 hari terakhir; jika milik Anda salah satunya, Anda juga akan menerima pemberitahuan ini melalui email. Panduan migrasi: [tautan]. Tidak ada yang berubah hingga 1 Maret 2027. Sejak tanggal itu endpoint v1 mengembalikan 410 Gone dengan tautan ke entri ini.

Setiap kalimat membawa sesuatu yang dibutuhkan pembaca. Jumlah integrasi yang terdampak memberi tahu setiap pembaca apakah harus terus membaca. “Tidak ada yang berubah hingga” adalah kalimat yang membiarkan yang tidak terdampak menutup tab-nya. Halaman contoh changelog mengumpulkan entri dari tim yang menulis bentuk ini secara konsisten, dan layak membaca tiga sebelum menulis yang pertama sendiri.

Header apa yang harus dikirim endpoint yang di-deprecate?

Kirim Deprecation, Sunset dan Link ke penggantinya, di setiap respons dari endpoint yang di-deprecate, sejak hari pengumuman. Header Deprecation membawa tanggal deprecation berlaku efektif; header Sunset membawa tanggal endpoint berhenti merespons; Link: <url>; rel="successor-version" menunjuk ke apa yang digunakan sebagai gantinya.

HTTP/1.1 200 OK
Deprecation: @1756425600
Sunset: Mon, 01 Mar 2027 00:00:00 GMT
Link: <https://api.example.com/v2/reports>; rel="successor-version"
Link: <https://example.com/changelog/daily-reports>; rel="deprecation"

Kebanyakan pemanggil tidak akan pernah membaca header itu sendiri. Nilainya adalah bahwa klien HTTP, gateway atau pemantauan milik pemanggil bisa, yang mengubah deprecation Anda menjadi peringatan di sisi mereka alih-alih halaman di sisi Anda. SDK yang Anda kirimkan seharusnya mencatat peringatan ketika melihat satu.

Siapa yang diberi tahu, dan bagaimana Anda tahu?

Ini langkah yang menentukan apakah sunset itu tenang atau menjadi insiden dukungan, dan ini yang paling sulit dilakukan hanya dengan changelog. Entri changelog memberi tahu semua orang yang membaca changelog. Deprecation harus mencapai orang-orang spesifik yang kodenya akan gagal, dan cara biasa menemukan mereka adalah data penggunaan yang sama yang dibutuhkan pengingat di tengah jalan: kunci API, aplikasi atau akun yang memanggil perilaku yang di-deprecate baru-baru ini.

Lingkaran yang kami jalankan: entri disusun dari pull request yang menambahkan deprecation, seseorang meninjau kata-kata dan tanggalnya, dan setelah diterbitkan entri itu sendiri adalah notifikasinya. Siapa pun yang masukan widget-nya tentang masalah itu, atau permintaan penggantinya, menjadi issue GitHub yang ditutup oleh pull request tersebut mendapat komentar di issue itu yang mengatakan itu sudah dirilis, dengan tautan ke entrinya. Feed dan widget melayani entri yang sama kepada semua orang lainnya, bersama setiap entri lain di changelog API. Yang tidak kami lakukan adalah membiarkan deprecation menjadi “dirilis” sebelum seseorang menerbitkannya; pemberitahuan dengan tanggal yang salah lebih buruk daripada tidak ada pemberitahuan.

Apa pun alat Anda, pertanyaan yang harus bisa Anda jawab pada hari sunset adalah: pemanggil mana yang masih menggunakan ini minggu lalu, dan yang mana dari mereka yang kami beri tahu langsung? Jika jawabannya “kami memposting tentang itu”, sunset-nya belum siap.

Apa perbedaan antara men-deprecate dan memversikan?

Memversikan adalah bagaimana Anda menjaga perilaku lama tetap tersedia sementara yang baru ada; deprecation adalah bagaimana Anda mempensiunkan yang lama. Versi API baru tanpa kebijakan deprecation untuk yang sebelumnya adalah komitmen untuk menjalankan keduanya selamanya. Deprecation tanpa versi adalah breaking change dengan penundaan. Anda membutuhkan keduanya, dan versi adalah bagian yang lebih mudah. GraphQL adalah pengecualian yang layak disebut: biasanya tidak ada nomor versi sama sekali untuk dinaikkan, dan deprecation skema GraphQL membahas bagaimana satu skema bersama mempensiunkan field dengan directive sebagai gantinya.

FAQ

Haruskah endpoint yang di-deprecate terus berfungsi persis seperti sebelumnya? Ya, hingga tanggal sunset. Satu-satunya perubahan yang diizinkan adalah header yang ditambahkan dan, mendekati akhir, brownout terjadwal yang Anda umumkan sebelumnya.

Kode status apa yang harus dikembalikan endpoint yang dipensiunkan? 410 Gone, dengan badan dan header Link yang menunjuk ke penggantinya dan entri changelog. 404 mengatakan URL-nya tidak pernah ada, yang salah dan tidak membantu.

Bisakah periode deprecation dipersingkat? Hanya untuk keamanan. Jika perilaku lama bisa dieksploitasi, katakan begitu, persingkat periodenya, dan beri tahu setiap pemanggil yang terdampak secara langsung alih-alih mengandalkan changelog.

Perlukah saya men-deprecate sebuah field, atau hanya seluruh endpoint? Field, parameter, nilai enum, default dan header semuanya membutuhkan perlakuan yang sama, karena masing-masing bisa merusak pemanggil yang benar. Field yang dihapus adalah deprecation paling umum dan paling sering dilewati.


Klaim teknis dalam artikel ini belum ditinjau secara independen. Jika ada yang keliru, beri tahu kami dan kami akan memperbaikinya.

Terkait di changeloop: Dokumentasi developer, Contoh changelog

changeloop
Tim di balik changelog yang menutup lingkaran. Pengguna meminta sesuatu, timmu mengirimkannya, yang meminta jadi tahu.