Değişim öngören dış uygulamalar için bir API tasarlamaya çalışmak kolay değildir, ancak biraz düşünülmüş bir şey daha sonra hayatı kolaylaştırabilir. Önceki sürüm işleyicilerini yerinde bırakarak geriye dönük uyumu sürdürürken gelecekteki değişiklikleri destekleyecek bir şema oluşturmaya çalışıyorum.
Bu makaledeki öncelikli endişe, belirli bir ürün / şirket için tanımlanmış tüm bitiş noktaları için hangi şablonun izlenmesi gerektiğidir.
Temel şema
Temel bir URL şablonu göz önüne alındığında https://rest.product.com/
, tüm hizmetlerin ve bunun gibi diğer dinlenmeye dayalı olmayan bitiş noktaları /api
ile birlikte bulunduğunu tasarladım . Bu nedenle temel uç noktaları şu şekilde oluşturabilirim:/auth
/doc
https://rest.product.com/api/...
https://rest.product.com/auth/login
https://rest.product.com/auth/logout
https://rest.product.com/doc/...
Hizmet Bitiş Noktaları
Şimdi son noktaların kendileri için. Endişe yaklaşık POST
, GET
, DELETE
bu makalenin temel amacı değildir ve bu eylemlerin kendileri üzerinde husustur.
Bitiş noktaları, ad alanlarına ve eylemlere bölünebilir. Her eylem, aynı zamanda, geri dönüş tipi veya gerekli parametrelerdeki temel değişiklikleri destekleyecek şekilde de kendini göstermelidir.
Kayıtlı kullanıcıların mesaj gönderebileceği varsayımsal bir sohbet hizmeti alarak aşağıdaki bitiş noktalarına sahip olabiliriz:
https://rest.product.com/api/messages/list/{user}
https://rest.product.com/api/messages/send
Şimdi gelecekteki API değişiklikleri için sürüm desteği eklemek, kırıcı olabilir. Sürüm imzasını sonradan sonra /api/
veya sonra ekleyebiliriz /messages/
. send
Son nokta göz önüne alındığında v1 için aşağıdakilere sahip olabiliriz.
https://rest.product.com/api/v1/messages/send
https://rest.product.com/api/messages/v1/send
Öyleyse benim ilk sorum, sürüm tanımlayıcısı için önerilen yer nedir?
Denetleyici Kodunu Yönetme
Şimdi, önceki sürümleri desteklememiz gerektiğine karar verdik, böylece zaman içinde kullanımdan kaldırılabilecek yeni sürümlerin her biri için bir şekilde kod işlemek zorundayız. Java'da uç noktalar yazdığımızı varsayarsak, bunu paketler aracılığıyla yönetebiliriz.
package com.product.messages.v1;
public interface MessageController {
void send();
Message[] list();
}
Bu, tüm kodların ad boşlukları ile ayrılması avantajına sahiptir; bu, herhangi bir kırılma değişikliğinin, hizmetin son noktalarının yeni bir kopyasının anlamına geleceği anlamına gelir. Bunun zararı, tüm kodların kopyalanması gerektiği ve her bir kopya için yeni ve önceki sürümlere uygulanacak hata düzeltmelerinin yapılması gerektiğidir.
Başka bir yaklaşım, her son nokta için işleyiciler oluşturmaktır.
package com.product.messages;
public class MessageServiceImpl {
public void send(String version) {
getMessageSender(version).send();
}
// Assume we have a List of senders in order of newest to oldest.
private MessageSender getMessageSender(String version) {
for (MessageSender s : senders) {
if (s.supportsVersion(version)) {
return s;
}
}
}
}
Bu şimdi sürümlemeyi her bir uç noktaya göre yalıtır ve çoğu durumda yalnızca bir kez uygulanması gereken hata hatalarını geri bağlantı noktasını uyumlu hale getirir, ancak bunu desteklemek için her bir uç nokta için daha adil bir iş yapmamız gerektiği anlamına gelir.
Bu yüzden benim ikinci sorum var: “Önceki sürümleri desteklemek için REST servis kodunu tasarlamak için en iyi yol nedir?”.