1 poin oleh GN⁺ 4 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Jika web API publik menggunakan nama seperti Product API bersama jalur /api/v1, versi semantik dan strukturnya bisa saling tidak selaras
  • Jika jalur /v1/ dan major.minor.patch dipakai bersamaan, route dan kontrak API jadi tercampur, dan angka pertama dari versi semantik terkunci di URL
  • Untuk perubahan yang memutus kompatibilitas, diperlukan jalur baru dan route reverse proxy, sehingga informasi kontrak bisa tersebar antara URL dan nomor versi
  • Jika API lanjutan dibuat secara bersamaan, API yang lama pada praktiknya terikat ke v1, dan saat terjadi perubahan yang memutus kompatibilitas setelahnya, makna nama dan jalurnya menjadi ambigu
  • Ini berangkat dari kegelisahan terhadap pola versioning web API publik yang berulang kali terasa mengganggu, sekaligus mencari prinsip desain yang lebih baik

1 komentar

 
GN⁺ 4 jam lalu
Pendapat Lobste.rs
  • Menaruh /v1/ di URL sebenarnya adalah salah satu keuntungan besar. Karena itu memaksa agar API tidak rusak bagi pengguna sampai endpoint tersebut dimatikan

  • Tulisan lain dari penulis yang sama seperti Evolving HTTP APIs memberi saran yang berguna

  • Pada dasarnya, setiap route diberi /v1/, /v2/, dan seterusnya untuk menandai perubahan yang memutus kompatibilitas. Jika ini adalah API publik yang dioperasikan, bukan standar yang ingin didefinisikan agar berjalan di banyak host, biasanya tidak banyak alasan untuk menerapkan semantic versioning secara penuh
    Semantic versioning ada agar pengembang lain bisa menaikkan dependensi dengan percaya diri tanpa harus membaca changelog selama 20 menit, tetapi pada API yang sedang beroperasi, orang tidak bisa memilih kapan mereka akan mengambil versi minor baru atau versi patch baru
    Yang dianggap sebagai perubahan yang memutus kompatibilitas adalah ketika perilaku yang didokumentasikan diubah, atau ketika klien lama yang bergantung pada perilaku yang didokumentasikan menjadi rusak. Ada juga yang menganggap perubahan pada perilaku yang tidak didokumentasikan sebagai breaking change, tetapi itu penuh risiko

  • Google melakukan seperti ini: AIP-185: API Versioning, AIP-180: Bacwards compatibility
    Dokumen desain ini terasa cukup spesifik pada cara kerja Google, tetapi saya tetap merujuknya saat mendesain API, dan beberapa idenya sangat berguna

  • Secara umum, menurut saya semua API harus berusaha meminimalkan perubahan yang memutus kompatibilitas semaksimal mungkin. Misalnya, jika ingin mengganti nama properti, menurut saya lebih baik menambahkan nama baru secara duplikat daripada menghapus properti lama
    Namun, cara the people at Buttondown do it juga rapi. Mereka mendefinisikan migrasi antar versi API, sehingga konsumen bisa menyematkan versi API mereka lewat header dan penyedia tetap bisa terus melakukan perubahan

    • Untuk properti output, pendekatan menduplikasi properti bekerja cukup baik. Tetapi pada input, Anda harus menangani kasus ketika klien mengirim dua properti itu dengan nilai yang berbeda
      Jawaban seperti “nama baru selalu diprioritaskan” memang terpikirkan, tetapi itu bisa gagal saat klien melakukan urutan baca-ubah-tulis dan mengirim kembali versi modifikasi dari objek yang dibuat server. Klien bisa saja hanya memperbarui properti lama dan mengabaikan properti baru, lalu mengirimkannya kembali apa adanya
    • Menyediakan migrasi antar versi API seperti yang dijelaskan penyedia API terdengar bagus, tetapi using an HTTP request header for versioning can cause problems
    • Tautan itu menjelaskan dengan sangat baik cara menangani bentuk data. Namun itu hanya sebagian masalahnya, dan saya penasaran bagaimana jika perilakunya sendiri berubah
      Transformasi seperti itu tampaknya juga bisa dipakai untuk pemetaan perilaku, tetapi kalau saya tidak melewatkannya, bagian itu tidak dibahas
  • Idealnya, versi dimasukkan ke dalam path, dan versi baru dibuat bersifat aditif. Dengan begitu, API versi lama bisa merutekan ulang permintaan ke versi API yang lebih baru setelah melakukan transformasi input/output yang diperlukan
    Beberapa tahun kemudian, saat tak ada lagi yang memakai versi lama, versi itu bisa dihapus, dan path /v1/ akan menghasilkan error

  • Dulu saya sempat sedikit membaca tentang versioning API melalui content negotiation lewat header Accept. Kalau ada yang pernah mengelola versioning API dengan cara itu, saya ingin tahu pengalamannya
    Dalam pengalaman saya, versioning per resource atau versioning global adalah pendekatan yang paling intuitif. Untuk deprecating, kombinasi menggunakan header respons HTTP Deprecation (RFC 9745) dan pada akhirnya mengembalikan respons seperti 410 Gone untuk endpoint lama tampak sebagai cara yang masuk akal untuk mendorong klien pindah ke versi baru
    Selain itu, saya juga sangat penasaran apakah ada yang pernah membuat API yang dapat berevolusi. Maksudnya, pendekatan yang menerjemahkan permintaan versi lama secara internal menjadi permintaan ke versi API baru, lalu benar-benar menghapus versi lama setelah klien bermigrasi atau setelah jangka waktu tertentu