Spring 3.2.x kullanarak bir REST API sürümünün nasıl yönetileceğini araştırıyorum, ancak bakımı kolay bir şey bulamadım. Önce sahip olduğum sorunu açıklayacağım, sonra bir çözümü ... ama burada tekerleği yeniden mi icat ettiğimi merak ediyorum.
Sürümü Accept başlığına göre yönetmek istiyorum ve örneğin bir istek Accept başlığına sahipse, application/vnd.company.app-1.1+json
Spring MVC'nin bunu bu sürümü işleyen yönteme iletmesini istiyorum. Ve bir API'deki tüm yöntemler aynı sürümde değişmediğinden, denetleyicilerimin her birine gitmek ve sürümler arasında değişmeyen bir işleyici için herhangi bir değişiklik yapmak istemiyorum. Ayrıca, Spring hangi yöntemi çağıracağını zaten keşfettiği için, denetleyicide hangi sürümün kullanılacağını (hizmet bulucuları kullanarak) anlamaya yönelik mantığa sahip olmak istemiyorum.
Dolayısıyla, 1.0 sürümünden 1.8'e bir işleyicinin 1.0 sürümünde tanıtıldığı ve v1.7'de değiştirildiği bir API'yi aldım, bunu aşağıdaki şekilde ele almak istiyorum. Kodun bir denetleyicinin içinde olduğunu ve sürümü başlıktan çıkarabilen bazı kodlar olduğunu hayal edin. (Aşağıdakiler İlkbaharda geçersizdir)
@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;
}
2 yöntem aynı RequestMapping
açıklamaya sahip olduğundan ve Yay yüklenemediğinden ilkbaharda bu mümkün değildir . Buradaki fikir, VersionRange
ek açıklamanın açık veya kapalı bir sürüm aralığını tanımlayabilmesidir. İlk yöntem 1.0'dan 1.6'ya kadar olan sürümler için geçerlidir, ikincisi ise 1.7 sürümü için geçerlidir (en son sürüm 1.8 dahil). Birisi 99.99 sürümünü geçmeye karar verirse bu yaklaşımın bozulacağını biliyorum, ancak bu benimle yaşamaya uygun bir şey.
Şimdi, baharın nasıl çalıştığına dair ciddi bir yeniden çalışma olmadan yukarıdakiler mümkün olmadığından, işleyicilerin isteklere uyma şeklini, özellikle de kendi isteklerimi yazmayı ProducesRequestCondition
ve orada sürüm aralığına sahip olmayı düşünüyordum. Örneğin
Kod:
@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;
}
Bu şekilde, açıklamanın üretim kısmında tanımlanmış kapalı veya açık sürüm aralıklarına sahip olabilirim. Şu anda bu çözüm üzerinde çalışıyorum, hala bazı çekirdek Spring MVC sınıflarını ( RequestMappingInfoHandlerMapping
, RequestMappingHandlerMapping
ve RequestMappingInfo
) değiştirmek zorunda kalmam sorunuyla, hoşuma gitmiyor, çünkü bu, daha yeni bir sürümüne yükseltmeye karar verdiğimde fazladan iş anlamına geliyor. yay.
Herhangi bir düşünceyi ve özellikle bunu daha basit, bakımı daha kolay bir şekilde yapma önerisini takdir ediyorum.
Düzenle
Bir ödül eklemek. Ödülü almak için, lütfen yukarıdaki soruyu, bu mantığın kontrol cihazının kendisinde olmasını önermeden cevaplayın. Spring, hangi denetleyici yönteminin çağrılacağını seçmek için zaten çok fazla mantığa sahip ve bunun üzerine piggyback yapmak istiyorum.
Düzenle 2
Orijinal POC'yi (bazı iyileştirmelerle) github'da paylaştım: https://github.com/augusto/restVersioning
produces={"application/json-1.0", "application/json-1.1"}
, Vb