Saya telah mencari cara mengelola versi REST API menggunakan Spring 3.2.x, tetapi saya belum menemukan apa pun yang mudah dipelihara. Saya akan menjelaskan terlebih dahulu masalah yang saya miliki, dan kemudian solusinya ... tetapi saya bertanya-tanya apakah saya menemukan kembali roda di sini.
Saya ingin mengelola versi berdasarkan header Terima, dan misalnya jika permintaan memiliki header Terima application/vnd.company.app-1.1+json
, saya ingin MVC musim semi untuk meneruskan ini ke metode yang menangani versi ini. Dan karena tidak semua metode dalam API berubah dalam rilis yang sama, saya tidak ingin membuka setiap pengontrol saya dan mengubah apa pun untuk penangan yang tidak berubah antar versi. Saya juga tidak ingin memiliki logika untuk mencari tahu versi mana yang akan digunakan dalam pengontrol itu sendiri (menggunakan pelacak layanan) karena Spring sudah menemukan metode mana yang harus dipanggil.
Jadi mengambil API dengan versi 1.0, ke 1.8 di mana penangan diperkenalkan di versi 1.0 dan dimodifikasi di v1.7, saya ingin menangani ini dengan cara berikut. Bayangkan kode tersebut ada di dalam pengontrol, dan ada beberapa kode yang dapat mengekstrak versi dari header. (Berikut ini tidak valid di Spring)
@RequestMapping(...)
@VersionRange(1.0,1.6)
@ResponseBody
public Object method1() {
// so something
return object;
}
@RequestMapping(...) //same Request mapping annotation
@VersionRange(1.7)
@ResponseBody
public Object method2() {
// so something
return object;
}
Ini tidak mungkin dilakukan pada musim semi karena 2 metode memiliki RequestMapping
anotasi yang sama dan Spring gagal dimuat. Idenya adalah bahwa VersionRange
anotasi dapat menentukan rentang versi terbuka atau tertutup. Metode pertama berlaku dari versi 1.0 hingga 1.6, sedangkan yang kedua untuk versi 1.7 dan seterusnya (termasuk versi terbaru 1.8). Saya tahu bahwa pendekatan ini rusak jika seseorang memutuskan untuk mengoper versi 99,99, tetapi itu adalah sesuatu yang tidak masalah bagi saya.
Sekarang, karena hal di atas tidak mungkin dilakukan tanpa pengerjaan ulang yang serius tentang cara kerja pegas, saya berpikir untuk mengutak-atik cara penangan yang cocok dengan permintaan, khususnya untuk menulis sendiri ProducesRequestCondition
, dan memiliki rentang versi di sana. Sebagai contoh
Kode:
@RequestMapping(..., produces = "application/vnd.company.app-[1.0-1.6]+json)
@ResponseBody
public Object method1() {
// so something
return object;
}
@RequestMapping(..., produces = "application/vnd.company.app-[1.7-]+json)
@ResponseBody
public Object method2() {
// so something
return object;
}
Dengan cara ini, saya dapat memiliki rentang versi tertutup atau terbuka yang ditentukan di bagian produksi anotasi. Saya sedang mengerjakan solusi ini sekarang, dengan masalah bahwa saya masih harus mengganti beberapa kelas inti Spring MVC ( RequestMappingInfoHandlerMapping
, RequestMappingHandlerMapping
dan RequestMappingInfo
), yang tidak saya sukai, karena itu berarti kerja ekstra setiap kali saya memutuskan untuk meningkatkan ke versi yang lebih baru dari musim semi.
Saya akan menghargai pemikiran apa pun ... dan terutama, saran apa pun untuk melakukan ini dengan cara yang lebih sederhana dan lebih mudah dipertahankan.
Sunting
Menambahkan hadiah. Untuk mendapatkan bounty, harap jawab pertanyaan di atas tanpa menyarankan untuk memiliki logika ini sendiri di controller. Spring sudah memiliki banyak logika untuk memilih metode pengontrol mana yang akan dipanggil, dan saya ingin mendukungnya.
Edit 2
Saya telah membagikan POC asli (dengan beberapa peningkatan) di github: https://github.com/augusto/restVersioning
produces={"application/json-1.0", "application/json-1.1"}
dll