Öngörülen değişiklikler için planlama REST bitiş noktaları için önerilen bir kalıp nedir


25

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ı /apiile 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, DELETEbu 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/. sendSon 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?”.

Yanıtlar:


13

Bu yüzden benim ikinci sorum var: “Önceki sürümleri desteklemek için REST servis kodunu tasarlamak için en iyi yol nedir?”.

Çok dikkatli bir şekilde tasarlanmış ve ortogonal bir API'nin muhtemelen geriye dönük uyumsuz şekillerde hiçbir zaman değiştirilmesi gerekmeyecektir, bu nedenle gerçekten en iyi yol gelecekteki sürümlere sahip olmamaktır.

Tabii ki, muhtemelen ilk denemeyi gerçekten alamayacaksınız; Yani:

  • Planladığınız gibi API'nizi versiyonlayın (ve versiyon içindeki API'dir, içindeki bireysel metodları değil) ve bu konuda çok fazla gürültü yapın. İş ortaklarınızın API'nin değişebileceğini ve uygulamalarının en son sürümü kullanıp kullanmadıklarını kontrol etmeleri gerektiğini bildiğinden emin olun; ve yeni bir tane olduğunda, kullanıcılara yükseltme yapmalarını tavsiye edin. İki eski sürümü desteklemek zordur, beşini desteklemesi imkansızdır.
  • Her "sürüm" ile API sürümünü güncelleme dürtüsüne karşı durun. Yeni özellikler, mevcut müşterileri kırmadan mevcut versiyona alınabilir; onlar yeni özellikler. İstediğiniz en son şey, müşterilerin sürüm numarasını görmezden gelmesidir , çünkü çoğunlukla zaten geriye dönük olarak uyumludur. API sürümünü yalnızca mevcut API'yi bozmadan ileriye gidemediğiniz zaman güncelleyin.
  • Yeni bir sürüm oluşturma zamanı geldiğinde, ilk müşteri önceki sürümün geriye dönük uyumlu uygulaması olmalıdır. "Bakım API'si", mevcut API'ye uygulanmalıdır. Bu şekilde, birkaç tam uygulamanın gerçekleştirilmesi için olmuyorsunuz; sadece geçerli sürüm ve eski sürümler için birkaç "kabuk". Artık kullanımdan kaldırılmış API için geriye dönük eşlenebilir istemciye karşı bir regresyon testi çalıştırmak, hem yeni API hem de uyumluluk katmanını test etmek için iyi bir yoldur.

3

İlk URI tasarım seçeneği, tüm API'yi versiyonladığınız fikrini daha iyi ifade eder. İkincisi, mesajların kendileri versiyonlanırken yorumlanabilir. Yani bu daha iyi IMO:

rest.product.com/api/v1/messages/send

İstemci kütüphanesi için ayrı Java paketlerinde iki tam uygulamanın kullanılmasının daha temiz, kullanımı kolay ve bakımı daha kolay olduğunu düşünüyorum.

Olduğu söyleniyor, sürüm geliştirmek yerine API'leri geliştirmek için daha iyi yöntemler var. Buna hazırlıklı olmanız gerektiğine katılıyorum, ancak son çare olarak dikkat çekmek ve dikkatli bir şekilde kullanmak için sürüm yapmayı düşünüyorum. Müşterilerin yükseltme yapması nispeten büyük bir çaba. Bir süre önce bu düşüncelerin bir kısmını bir blog yazısına koydum:

http://theamiableapi.com/2011/10/18/api-design-best-practice-plan-for-evolution/

Özellikle REST API sürümleri için, bu notu Mark Nottingham'dan faydalı bulabilirsiniz:

http://www.mnot.net/blog/2011/10/25/web_api_versioning_smackdown


3

API sürümlerini işlemek için başka bir yaklaşım, HTTP Başlıklarında Sürüm kullanmaktır. Sevmek

POST /messages/list/{user} HTTP/1.1
Host: http://rest.service.com
Content-Type: application/json
API-Version: 1.0      <----- like here
Cache-Control: no-cache

Başlığı ayrıştırabilir ve arka uçta uygun şekilde kullanabilirsiniz.

Bu yaklaşımla, müşterilerin URL’yi, sadece başlığını değiştirmeleri gerekmez. Ayrıca bu, REST uç noktalarını her zaman daha temiz hale getirir.

Herhangi bir müşteri sürüm başlığını göndermediyse, 400 - Kötü istek gönderirsiniz veya API'nizin geriye dönük olarak uyumlu bir sürümüyle işleyebilirsiniz .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.