HATEOAS: mutlak mı yoksa göreli URL'ler mi?


Yanıtlar:


83

İnsanlar "göreceli URI" derken ince bir kavramsal belirsizlik vardır.

By RFC 3986 tanımına , genel URI içerir:

  URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

  hier-part   = "//" authority path-abempty
              / path-absolute
              / path-rootless
              / path-empty

     foo://example.com:8042/over/there?name=ferret#nose
     \_/   \______________/\_________/ \_________/ \__/
      |           |            |            |        |
   scheme     authority       path        query   fragment

Zor olan, şema ve otorite ihmal edildiğinde, "yol" kısmının kendisi ya mutlak bir yol (ile başlar /) ya da "köksüz" bir göreceli yol olabilir. Örnekler:

  1. Bir mutlak URI veya tam URI:"http://example.com:8042/over/there?name=ferret"
  2. Ve bu, mutlak yolu olan göreceli bir uri'dir :/over/there
  3. Ve bu göreceli bir yolla göreli bir uri'dir : hereveya ./hereveya ../hereveya vb.

Öyleyse, soru "bir sunucunun dinlendirici yanıtta göreli yol üretip üretmeyeceği " ise, yanıt "Hayır" dır ve ayrıntı nedeni burada mevcuttur . Bence çoğu insan (beni dahil) "göreli URI" ye karşı aslında "göreli yola" karşıdır.

Ve pratikte çoğu sunucu tarafı MVC framework kolayca oluşturabilir mutlak yolu ile göreli URI gibi /absolute/path/to/the/controllerve soru "sunucu uygulaması önüne gerekip gerekmediğini olur scheme://hostname:portmutlak yolun önünde". OP'nin sorusu gibi. Bundan tam olarak emin değilim.

Bir yandan, sunucunun tam bir URI döndürmesinin tavsiye edildiğini düşünüyorum. Bununla birlikte, sunucu hiçbir zaman hostname:portkaynak kodunun içindeki şeyi bu şekilde kodlamamalıdır (aksi takdirde, mutlak yolla göreli uri'ye geri dönmeyi tercih ederim). Çözüm, sunucu tarafında bu öneki her zaman HTTP isteğinin "Host" başlığından almaktır. Bunun her durumda işe yarayıp yaramadığından emin değilim.

Öte yandan, müşterinin http://example.com:8042mutlak yolu birleştirmesi çok zahmetli görünmüyor . Sonuçta, istemci isteği sunucuya gönderdiğinde bu düzeni ve etki alanı adını zaten biliyor değil mi?

Sonuçta, diyebilirim ki, mutlak URI, muhtemelen mutlak yol ile göreli URI'ye geri dönüş, asla göreli yol kullanmamanızı tavsiye ederim .


2
Bu, nihai sonuç dışında hemfikir olduğum iyi bir cevap (+1). Ancak cevabımda, HTTP spesifikasyonunun, örnek olarak , "mutlak" ifadesini tam olarak nitelenmiş bir URI'ye değil, mutlak bir yola başvurmak için tanımladığını iddia ediyorum . O - I (2), kayıt katılmıyorum Yani olan bir tam URI değil yani istemci, ağ protokolü ve ana anlaması gerekir hangi bir mutlak URI ama. Ve bu nedenle, hem tam bir URI hem de mutlak URI olan (1) tanımınıza da katılmıyorum .
Lawrence Dol

Yorum için teşekkürler. Dosya sisteminden mutlak yol ve göreceli yol kavramını ödünç alıyorum. Farklı terimler bir yana, senin fikrinle benimki arasında önemli bir fark görmüyorum. Ayrıca form 1 ve 2'yi öneriyorsunuz ve form 3'e karşı çıkıyorsunuz, değil mi?
RayLuo

2
Pratik olarak konuşursak, ben (2) için varım; Bence (1) arka ucun çok fazla HTTP'ye özgü bilgiye sahip olmasını gerektiriyor (genel olarak HTTP değil, belirli HTTP ortamının ayrıntıları hakkında anlam ifade ediyor) ve (3) istemcinin çok fazlasını gerektiriyor gibi görünüyor. Ancak , gerekçem orijinal taslak şartnameye dayanıyordu ve örnekler daha sonraki bir sürümde, gerekçelerimi geçersiz kılacak şekilde değiştirildi.
Lawrence Dol

Şahsen ben (henüz) HATEOAS'a hiç ikna olmadım ve bu nedenle URI'ların geri gönderilmesi talebi bir API için bu kadar mantıklı. API'lerimin istemcide bir web sitesine göz atmaya benzer bir şekilde yönlendirildiğini görmüyorum; kullanım durumları büyük ölçüde adhoc işlevi tarafından yönlendirilir.
Lawrence Dol

@LawrenceDol Başlangıçta HATEOAS konusunda aynı kafa karışıklığım var. Şimdi bunu bir seçim meselesi olarak görüyorum. Müşterileriniz api'nizi kesinlikle kullanmak için adhoc işlevini kullanabilir, ancak isterlerse / isterseniz, onlar / siz yine de takip etmeleri için bir kalıp geliştirebilirsiniz, böylece istemcinin her bir URL'yi sabit kodlaması gerekmez. Bu HATEOAS'tır.
RayLuo

13

Müşteri kodunu kimin yazdığına bağlıdır. İstemci ve sunucuyu yazıyorsanız, o zaman pek bir fark yaratmaz. URL'leri istemcide veya sunucuda oluşturmanın acısını çekeceksiniz.

Ancak, sunucuyu oluşturuyorsanız ve diğer kişilerin istemci kodu yazmasını bekliyorsanız, tam URI'ler sağlarsanız sizi daha çok seveceklerdir. Göreli URI'leri çözmek biraz zor olabilir. Öncelikle bunları nasıl çözeceğiniz, döndürülen ortam türüne bağlıdır. Html temel etikete sahiptir, Xml her iç içe geçmiş öğede xml: base etiketlerine sahip olabilir, Atom beslemelerinin feed'de bir tabanı ve içerikte farklı bir tabanı olabilir. Müşterinize temel URI hakkında açık bilgi sağlamazsanız, temel URI'yi istek URI'sinden veya belki Content-Location başlığından almaları gerekir! Ve sondaki eğik çizgiye dikkat edin. Temel URI, son eğik çizginin sağındaki tüm karakterler yok sayılarak belirlenir. Bu, izleyen eğik çizginin göreli URI'leri çözümlerken artık çok önemli olduğu anlamına gelir.

Küçük bir değinmeyi gerektiren diğer tek sorun belge boyutudur. Her bir öğenin birden çok bağlantıya sahip olabileceği büyük bir öğe listesi döndürüyorsanız, varlığı sıkıştırmazsanız, mutlak URL'lerin kullanılması varlığınıza önemli miktarda bayt ekleyebilir. Bu mükemmel bir sorundur ve duruma göre önemli olup olmadığına karar vermeniz gerekir.


11

Tek gerçek fark, istemciler için göreli sürümden oluşturmak zorunda kalmadan mutlak URI'ler tüketiyorlarsa bunun daha kolay olduğu görünmektedir. Tabii ki, bu fark beni mutlak versiyonu yapmam için etkilemek için yeterli olacaktır.


7

Uygulamanız ölçeklenirken, yük dengeleme, yük devretme vb. Yapmak isteyebilirsiniz. Mutlak URI'ler döndürürseniz, istemci tarafındaki uygulamalarınız gelişen sunucu yapılandırmanızı takip edecektir.


"Mutlak" ı mutlak yol (ör. /xxx/yyy...) Olarak tanımlamanız ve tam bir URI anlamına gelmemesi koşuluyla (ör. http://api.example.com/xxx/yyy...).
Lawrence Dol

6

RayLou'nun trichotomisini kullanma organizasyonum (2) 'yi tercih etmeyi seçti. Birincil neden, XSS (Siteler Arası Komut Dosyası) saldırılarından kaçınmaktır. Sorun şu ki, bir saldırgan sunucudan gelen yanıta kendi URL köklerini enjekte edebiliyorsa, sonraki kullanıcı istekleri (kullanıcı adı ve parolayla kimlik doğrulama isteği gibi) saldırganın kendi sunucusuna iletilebilir *.

Bazıları, yük dengeleme için istekleri başka sunuculara yeniden yönlendirebilme sorununu gündeme getirdi, ancak (bu benim uzmanlık alanım olmasa da) istemcileri açıkça farklı bir yere yönlendirmek zorunda kalmadan yük dengelemeyi etkinleştirmenin daha iyi yolları olduğuna bahse girerim. ana bilgisayarlar.

* Lütfen bu muhakemede herhangi bir kusur olup olmadığını bana bildirin. Amaç elbette tüm saldırıları önlemek değil, en az bir saldırı yolunu engellemektir.


Önceki cevabımın kuruluşunuza yardımcı olmasına sevindim. Evet, şahsen ben de (2) yani şemasız mutlak yolu tercih ediyorum. Ancak gerekçenizi merak ediyorum. Müşterinizin yalnızca şemasız URL'nizi kabul etmesini nasıl sağladınız? Tarayıcı gibi genel bir istemci, şemasız bir url'yi hiç reddetmez. Bu yüzden, url'leri gerçekten takip etmeden önce doğrulamak için kendi istemci tarafı kodunuzu yazmanız gerektiğini varsayıyorum. Bu teknik olarak yapılabilir (ancak mutlaka yararlı değildir), ancak bu tür bir istemci tarafı doğrulama tipik olarak REST veya HATEOAS tartışmasının bir parçası değildir.
RayLuo

3
Bunun eski bir gönderi olduğunu biliyorum, ancak "eğer bir saldırgan geri gelen yanıta kendi URL köklerini enjekte edebilirse" nin bir tür saçma neden olduğunu belirtmek istiyorum . Yanıtta doğru yerlere "kendi URL'lerini enjekte" edebiliyorlarsa, bahse girerim ki, aynı kolaylıkla ana bilgisayar adınızı kendi adresleriyle değiştirebilirler. Dolayısıyla, güvenlik açısından, bunu geçerli bir argüman olarak görmüyorum.
Magnus Eriksson

5

Her zaman tam URL'yi kullanmalısınız. URL'lerin tümünün benzersiz olması gerektiğinden, kaynak için benzersiz tanımlayıcı görevi görür.

Ayrıca tutarlı olmanız gerektiğini de iddia ediyorum. Konum HTTP başlığı, HTTP belirtimine dayalı olarak tam bir URL beklediğinden, tam URL, yeni bir kaynak oluşturulduğunda istemciye Konum başlığında geri gönderilir. Konum başlığında tam bir URL ve ardından yanıt metninizdeki bağlantılarda göreceli URI'ler sağlamanız garip olurdu.


1
Konum başlığının HTTP spesifikasyonu mutlak URI diyor. Mutlak bir URI bir şema içermelidir (ör. Http).
Mark Bober

Ancak sorun, bağlamsız opak tanımlayıcıların nasıl oluşturulacağı değil, bağlantıların nasıl oluşturulacağını soruyor . İkincisi, haklı olarak "bu belge ile aynı ağ konumunda" çıkarım yapabilir ve bu, spesifikasyonun Locationbaşlık örneğinin verdiği şeydir - URI şemasını veya sunucunun ağ konumunu içermeyen mutlak bir URI. Bağlantılar ve kimlikler genellikle birbirine karıştırılırken aynı şey değildir - ilki bağlamlıdır, ikincisi yoktur.
Lawrence Dol

Spesifikasyonun bahsettiğiniz kısmına bir bağlantı gönderebilir misiniz?
Mark Bober

Mutlak bir URI bir şemayı belirtir; mutlak olmayan bir URI'nin göreli olduğu söylenir. URI'ler ayrıca opak veya hiyerarşik olmalarına göre sınıflandırılır. Opak URI, şemaya özgü bölümü eğik çizgi ('/') ile başlamayan mutlak bir URI'dir. Opak URI'ler daha fazla ayrıştırmaya tabi değildir. Opak URI'lerin bazı örnekleri şunlardır: mailto: java-net@java.sun.com news: comp.lang.java urn: isbn: 096139210x
Mark Bober

1
Hey endişelenme dostum. Bu şeylerle ilgili bir diğer nokta da, href'leri kimlik olarak kullanan insanlar gördüm. Böylece istemcinin URL'yi bazı yapılandırma dosyasından ve bir kimlikten yeniden yapılandırması gerekmez, yalnızca URL'yi bilir ve buna göre önbelleğe alabilir.
Mark Bober

2

Büyük API sonuçlarında önemli bir husus, tam URI'yi tekrar tekrar dahil etmenin fazladan ağ yüküdür. İster inanın ister inanmayın, gzip bu sorunu tamamen çözmez (neden olduğundan emin değilim). Bir sonuca yüzlerce bağlantı dahil edildiğinde tam URI'nin ne kadar yer kapladığına şaşırdık.


2

Mutlak URI kullanmanın bir dezavantajı, api'nin proxy'ye bağlanamamasıdır.

Geri al ... doğru değil. Alan dahil olmak üzere tam bir URL'ye gitmelisiniz.


3
Mutlak URI neden proxy'nin ana bilgisayar adını kullanamıyor?
Ed Summers

1
Şu anda tam olarak bu sorun üzerinde çalışıyorum. Tüm isteklerin önce bir tür "yük dengeleme" katmanından geçmesini istiyoruz. Doğrudan sunuculara yönelik mutlak URI'ler bu modeli bozacaktır.
mag382

1
Mutlak URL'lere sahip bir siteyi proxy yapmak için Nginx kullanıyorum. Arka uç URL'sini eşdeğer proxy URL'si ile mükemmel şekilde değiştirebilir. Spesifik olarak windyroad.artifactoryonline.com'u (tam nitelikli URL'leri ve tam nitelikli yönlendirmeleri olan) repo.windyroad.com.au'ya proxy yapıyor
Tom Howard

2

Profesyonellerle ilgili olarak, bir müşterinin (mutlak) yol için ihtiyaç duyduğu ekstra işlem pahasına iletilecek baytlarda azalma görüyorum. Gzip olarak içerik kodlamayı denedikten sonra bile her baytı kaydetme konusunda çaresizseniz, önbelleğe alma başlıklarının doğru kullanımı, etag'lerin kullanımı ve istemcide koşullu istekler, sonunda bu gerekli olabilir, ancak Çabalarınız başka yerdeydi.

Eksileri ile ilgili olarak, gelecekte kaynaklar arasında müşteri akışını nasıl yönlendirebileceğiniz konusunda bir kontrol kaybı görüyorum (yük dengeleme, A / B testi, ...) ve bunun bir web yönetimiyle ilgili kötü bir uygulama olduğunu düşünüyorum. API. Sağladığınız URL artık müşteri için temelde opak değil ( URI opaklığı hakkında Tim Berners-Lee Web Mimarisi Axioms'a bakın ). Sonunda, yalnızca URL alanınızın yapısıyla ilgili olsa bile, müşterilerinizi API'nizin yaratıcı kullanımlarından memnun tutmaktan sorumlu olursunuz. Açıkça tanımlanmış bir URL değişikliğine izin vermeniz gerekirse , Köprü Metni Uygulama Dili'nde kullanılan URI şablonlarının kullanımını göz önünde bulundurun .

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.