REST URI'leri nasıl sürümlenir


Yanıtlar:


34

Bunu URI'nin bir parçası yapmanın (seçenek 1) en iyisi olduğunu söyleyebilirim çünkü v4, v3'ten farklı bir kaynağı tanımlar. İkinci seçeneğinizdeki gibi sorgu parametreleri , kaynak yerine istekle ilgili ek (sorgu) bilgileri iletmek için en iyi şekilde kullanılabilir .


11
Soru şu ki, tartıştığımız farklı bir KAYNAK mı? Veya bu kaynağın farklı bir temsili? REST, temsil ve kaynak arasında bir ayrım yapar mı?
Cheeso

1
@Cheeso - OP, farklı bir kaynaktan ziyade farklı bir temsil olduğunu gösterir, dolayısıyla cevabım.
Greg Beech

Bu, buradan önce daha ayrıntılı bir şekilde yanıtlanmıştır stackoverflow.com/q/389169/104261
Taras Alenin

"İkinci seçeneğinizdeki gibi sorgu parametreleri için +1, kaynak yerine istekle ilgili ek (sorgu) bilgileri iletmek için en iyi şekilde kullanılabilir"
andy

Farklı temsiller için "Kabul Et" gibi başlıklar kullanmanız gerektiğini düşünüyorum, daha sonra istemci sunucuya "Sadece sürüm 4'ü kabul ediyorum" seçeneğini belirleyebilir ve sunucu bu gösterimle yanıt verebilir. Kabul gönderilmezse, son sürüm sağlanır.
Carlos Verdes

191

URL'leri versiyonlamayın çünkü ...

  • kalıcı bağlantıları kırıyorsun
  • Url değişiklikleri, arayüzünüz aracılığıyla bir hastalık gibi yayılacaktır. Değişmeyen ancak değişen temsile işaret eden temsillerle ne yaparsınız? URL'yi değiştirirseniz, eski istemcileri bozarsınız. URL'yi bırakırsanız, yeni müşterileriniz çalışmayabilir.
  • Ortam türlerini sürümleme çok daha esnek bir çözümdür.

Kaynağınızın bir çeşit application / vnd.yourcompany.user + xml döndürdüğünü varsayarsak, yapmanız gereken tek şey yeni bir uygulama / vnd.yourcompany.userV2 + xml ortam türü için destek oluşturmak ve v1'iniz ve v2 müşterileri barış içinde bir arada yaşayabilir.

Bir RESTful arayüzünde, bir sözleşmeye en yakın şey, istemci ve sunucu arasında değiş tokuş edilen ortam türlerinin tanımıdır.

İstemcinin sunucuyla etkileşimde bulunmak için kullandığı URL'ler, önceden alınan temsillere gömülü sunucu tarafından sağlanmalıdır. İstemci tarafından bilinmesi gereken tek URL, arayüzün kök URL'sidir. URL'lere sürüm numaraları eklemek, yalnızca istemcide URL'ler oluşturduğunuzda bir değer taşır, bunu bir RESTful arabirimiyle yapmamanız gerekir.

Medya türlerinizde mevcut müşterilerinizi bozacak bir değişiklik yapmanız gerekiyorsa, yeni bir tane oluşturun ve URL'lerinizi rahat bırakın!

Ve şu anda medya türleri olarak application / xml ve application / json kullanıyorsam bunun bir anlam ifade etmediğini söyleyen okuyucular için. Bunları nasıl değiştireceğiz? Değilsin. Bu medya türleri, kod indirmeyi kullanarak ayrıştırmadığınız sürece bir RESTful arabirimi için oldukça faydasızdır, bu noktada sürüm oluşturma tartışmalı bir noktadır.


66
Madde işaretlerini ele almak için. 1. Perma bağlantılarını koparmazsınız, çünkü kalıcı bağlantılar belirli bir sürüme bağlanır 2. Her şey sürümlendirilmişse, bu bir sorun değildir. Eski url'ler hala çalışabilir. İdeal olarak, sürüm 4 URL'sinin sürüm 3 kaynağına bir ilişki döndürmesini istemezsiniz. 3. Belki
Mike Pone

10
Bir web tarayıcısının yeni bir sürümüne yükselttiğinizde, yer imlerine eklediğiniz tüm favorilerinizin kırıldığını hayal edin! Kavramsal olarak kullanıcının, bir kaynağın temsilinin bir sürümüne değil, bir kaynağa bağlantı kaydettiğini unutmayın.
Darrel Miller

11
@Gili Bir REST api'nin kendi kendini açıklayıcı olması gerekliliğini karşılamak için, içerik türü başlığının mesajın tam anlamsal tanımını sağlaması gerekir. Başka bir deyişle, medya türünüz veri sözleşmenizdir. Application / xml veya application / json'ı teslim ederseniz, istemciye o XML / Json'da ne olduğu hakkında hiçbir şey söylemiyorsunuz demektir. Bir istemci uygulamasının bir çeker / Müşteri / Ad'a ulaştığı an, mesajda olmayan bilgilere dayalı olarak birleştirme oluşturuyorsunuz. Bant dışı bağlantının ortadan kaldırılması, DİNLENME sağlamak için çok önemlidir.
Darrel Miller

6
@Gili İstemci, kök URL dışında API URL'leri hakkında önceden bilgi sahibi olmamalıdır. Temsil biçimlerini belirli URL'lere bağlamamalısınız. Ortam türlerini seçmeye gelince, gerçekten application / vnd.mycompany.myformat + xml gibi belirli bir format veya XHtml, Atom, RDF vb. Gibi standartlaştırılmış bir format arasında seçim yapmanız gerekir.
Darrel Miller,

4
API sürümünü ayrı bir başlık alanı olarak koymak mantıklı mı? Şöyle: Kabul et: uygulama / com.example.myapp + json; sürüm = 1.0
Erik

21

Ah, eski huysuz şapkamı tekrar takıyorum.

ReST açısından bakıldığında, hiç önemli değil. Sosis değil.

İstemci, takip etmek istediği bir URI alır ve bunu opak bir dizge olarak değerlendirir. İçine istediğinizi koyun, müşterinin sürüm tanımlayıcı gibi bir şey hakkında hiçbir bilgisi yoktur .

Müşterinin bildiği şey, medya türünü işleyebileceğidir ve Darrel'ın tavsiyelerine uymanızı tavsiye ederim. Ayrıca ben şahsen, dinlendirici bir mimaride kullanılan formatı 4 kez değiştirme ihtiyacının, ciddi şekilde yanlış bir şey yaptığınıza dair devasa büyük uyarı işaretleri getirmesi gerektiğini ve medya türünüzü değişime dayanıklılık için tasarlama ihtiyacını tamamen atlatmanız gerektiğini düşünüyorum.

Ancak her iki durumda da müşteri yalnızca anlayabileceği biçime sahip bir belgeyi işleyebilir ve içindeki bağlantıları izleyebilir. Bağlantı ilişkilerini (geçişleri) bilmelidir. Yani URI'de ne olduğu tamamen alakasızdır.

Ben şahsen http: // localhost / 3f3405d5-5984-4683-bf26-aca186d21c04 için oy verirdim

Başka herhangi bir istemci geliştiricisinin veya sisteme dokunan kişinin bir URI'nin başına veya sonuna v4'ü koyması gerekip gerekmediğini sorgulamasını engelleyecek mükemmel bir şekilde geçerli bir tanımlayıcı (ve sunucu açısından 4'e sahip olmamanızı öneririm. sürümler, ancak 4 ortam türü).


Ya temsilin önemli ölçüde değişmesi gerekiyorsa ve geriye dönük olarak uyumlu değilse?
Mike Pone

1
Ortam türünüzü, ad alanları ve genişletilebilir bir xsd veya mevcut xml formatları ike atom gibi genişletilebilir bir şekilde tasarlayarak, bu önlenebilir olmalıdır. Gerçekten mecbursanız, başka bir medya türü gitmenin yoludur.
SerialSeb

1
Bu tamamen geçerli cevabı beğendim, ancak önerilen URI'nin, 'hacklenebilir' URI'ler istediğiniz gerçek bir senaryodan çok, noktayı göstermek için olduğunu düşünüyorum.
Dave Van den Eynde

10

Sürümü URL'ye YERLEŞTİRMEMELİSİNİZ, sürümü isteğin Kabul Başlığına koymalısınız - bu ileti dizisindeki yazıma bakın:

API sürüm belirleme için en iyi uygulamalar?

URL'ye sürüm yapıştırmaya başlarsanız, bunun gibi saçma URL'lerle karşılaşırsınız: http://company.com/api/v3.0/customer/123/v2.0/orders/4321/

Ve içeri giren bir dizi başka sorun da var - bloguma bakın: http://thereisnorightway.blogspot.com/2011/02/versioning-and-types-in-resthttp-api.html


11
Üzgünüm ama bunun gibi saçma URL'lerle karşılaşacağını sanmıyorum. Sürüm numaralarını belirli bir kaynağa veya (daha kötüsü) belirli bir temsile bağlıyorsunuz. Bu aptalca olurdu, IMO. Aksine, API'nin sürümünü oluşturuyorsunuz, böylece URI'de asla birden fazla sürümünüz olmayacak.
fool4jesus


3

API'yi versiyonlamak için 4 farklı yaklaşım vardır:

  • URI yoluna sürüm eklemek:

    http://example.com/api/v1/foo
    
    http://example.com/api/v2/foo
    

    Değişikliği bozduğunuzda, sürümü şu şekilde artırmalısınız: v1, v2, v3 ...

    Kodunuza aşağıdaki gibi bir denetleyici uygulayabilirsiniz:

    @RestController
    public class FooVersioningController {
    
    @GetMapping("v1/foo")
    public FooV1 fooV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping("v2/foo")
    public FooV2 fooV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Parametre versiyonunu isteyin:

    http://example.com/api/v2/foo/param?version=1
    http://example.com/api/v2/foo/param?version=2
    

    API'nin nasıl kullanılmasını istediğinize bağlı olarak sürüm parametresi isteğe bağlı veya gerekli olabilir.

    Uygulama şuna benzer olabilir:

    @GetMapping(value = "/foo/param", params = "version=1")
    public FooV1 paramV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping(value = "/foo/param", params = "version=2")
    public FooV2 paramV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Özel bir başlık geçirme:

    http://localhost:8080/foo/produces
    

    Başlıklı:

    headers[Accept=application/vnd.company.app-v1+json]
    

    veya:

    headers[Accept=application/vnd.company.app-v2+json]
    

    Bu şemanın en büyük avantajı çoğunlukla anlambilimdir: URI'yi sürüm oluşturma ile ilgili herhangi bir şeyle karıştırmıyorsunuz.

    Olası uygulama:

    @GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v1+json")
    public FooV1 producesV1() {
        return new FooV1("firstname lastname");
    }
    
    @GetMapping(value = "/foo/produces", produces = "application/vnd.company.app-v2+json")
    public FooV2 producesV2() {
        return new FooV2(new Name("firstname", "lastname"));
    }
    
  • Ana Bilgisayar Adlarını Değiştirme veya API Ağ Geçitlerini Kullanma:

    Esasen, API'yi bir ana bilgisayar adından diğerine taşıyorsunuz. Hatta bunu aynı kaynaklara yeni bir API oluşturmaya bile çağırabilirsiniz.

    Ayrıca, API Ağ Geçitlerini kullanarak bunu yapabilirsiniz.


2

REST hizmetleri kullanımdan önce kimlik doğrulaması gerektiriyorsa, API anahtarını / jetonunu bir API sürümüyle kolayca ilişkilendirebilir ve yönlendirmeyi dahili olarak yapabilirsiniz. API'nin yeni bir sürümünü kullanmak için, o sürüme bağlanan yeni bir API anahtarı gerekebilir.

Ne yazık ki, bu çözüm yalnızca yetkilendirmeye dayalı API'ler için çalışıyor. Ancak, sürümleri URI'lerin dışında tutar.



1

Sürümü, URI'nin sonuna isteğe bağlı bir değer olarak eklerdim. Bu, / V4 gibi bir son ek veya açıkladığınız gibi bir sorgu parametresi olabilir. Hatta / V4'ü sorgu parametresine yönlendirebilir, böylece her iki varyasyonu da destekleyebilirsiniz.


1

Sürüm oluşturma için URI kullanırsanız, sürüm numarası API kökünün URI'sinde olmalıdır, böylece her kaynak tanımlayıcı bunu içerebilir.

Teknik olarak bir REST API, URL değişikliklerine (tek tip arayüz kısıtlamasının sonucu) göre bozulmaz. Yalnızca ilgili semantik (örneğin API'ye özgü bir RDF sözlüğü) geriye dönük olmayan uyumlu bir şekilde (nadir) değiştiğinde bozulur. Şu anda pek çok kişi, REST yanıtlarını (kendi kendini tanımlayan mesaj kısıtlaması) açıklamak için gezinme bağlantıları (HATEOAS kısıtlaması) ve sözcükler kullanmamaktadır, bu nedenle müşterileri bozulur.

Özel MIME türleri ve MIME türü sürüm oluşturma işe yaramaz çünkü ilgili meta verileri ve temsilin yapısını kısa bir dizeye koymak işe yaramaz. Ofc. meta veriler ve yapı sık sık değişecek ve bu nedenle sürüm numarası da ...

Bu nedenle, sorunuzu yanıtlamak için, isteklerinizi ve yanıtlarınızı sözcüklerle ( Hydra , bağlantılı veriler ) not almanın ve sürüm oluşturmayı unutmanın veya yalnızca geriye dönük uyumlu olmayan sözcük değişiklikleri kullanarak kullanmanın en iyi yolu (örneğin, bir sözcüğü başka bir sözcükle değiştirmek istiyorsanız).


0

Bunu mime türünde yapmak için oy veriyorum ama URL'de değil. Ama sebep diğer erkeklerle aynı değil.

Benzersiz kaynağı bulmak için URL'nin benzersiz (bu yönlendirmeler hariç) olması gerektiğini düşünüyorum. Öyleyse, /v2.0URL’leri kabul ediyorsanız , neden /ver2.0veya /v2/veya değil /v2.0.0? Veya hatta -alphave -beta? (sonra tamamen semver kavramı olur )

Dolayısıyla, mime türündeki sürüm, URL'den daha kabul edilebilir.

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.