REST HATEOAS (olgunluk seviyesi 3) ne kadar yararlı / önemli?


110

Bazı kıdemli ekip üyelerinin bir REST API'nin HATEOAS uyumlu olması ve Richardson'un tüm olgunluk seviyelerini uygulaması gerektiğine inandıkları bir projeye dahil oluyorum ( http://martinfowler.com/articles/richardsonMaturityModel.html )!

AFAIK çoğu REST uygulaması HATEOAS uyumlu değildir ve daha fazla insanın bunu yapmaması için iyi bir neden olmalıdır. Ek karmaşıklık, çerçeve eksikliği (sunucu ve istemci tarafları), performans endişesi ve ... gibi nedenleri düşünebilirim.

Ne düşünüyorsun? Gerçek bir dünya projesinde HATEOAS ile herhangi bir deneyiminiz oldu mu?


İşte konuyla ilgili güzel bir makale: medium.com/@andreasreiser94/… Temel olarak, "REST" in normalde uygulanma şekli,
RPC'dir

Yanıtlar:


213

REST topluluğundaki hiç kimse REST'in kolay olduğunu söylemiyor. HATEOAS, REST mimarisine zorluk katan özelliklerden sadece biridir.

İnsanlar önerdiğiniz tüm nedenlerden dolayı HATEOAS yapmaz: bu zor. Hem sunucu tarafına hem de istemciye karmaşıklık katar (eğer gerçekten bundan yararlanmak istiyorsanız).

ANCAK bugün milyarlarca insan REST'in faydalarını yaşıyor. Amazon'da "ödeme" URL'sinin ne olduğunu biliyor musunuz? Yapmıyorum. Yine de her gün kontrol edebilirim. Bu URL değişti mi? Bilmiyorum, umrumda değil.

Önemsediğini biliyor musun? Ekran yazan herkes Amazon otomatik istemcisini kazıdı. Muhtemelen zahmetli bir şekilde web trafiğini koklayan, HTML sayfalarını okuyan, hangi bağlantıların ne zaman ve hangi yüklerle arayacağını bulmak için.

Amazon dahili süreçlerini ve URL yapısını değiştirir değiştirmez, bu sabit kodlu istemciler başarısız oldu - çünkü bağlantılar koptu.

Yine de, sıradan web sörfçüleri gün boyu neredeyse hiç aksamadan alışveriş yapabildiler.

Bu, iş başında REST, sadece metin tabanlı arayüzü yorumlayabilen ve sezebilen, küçük bir grafiği bir alışveriş sepeti ile tanıyan ve bunun gerçekte ne anlama geldiğini anlayabilen insan tarafından artırıldı.

Yazılım yazan çoğu insan bunu yapmaz. Otomatik istemciler yazan çoğu kişi umursamıyor. Çoğu insan, müşterilerini bozduklarında düzeltmeyi, uygulamayı ilk etapta kırılmayacak şekilde yapılandırmaktan daha kolay bulur. Çoğu insanın önemli olduğu yerde yeterli müşterisi yoktur.

Değişiklikleri hızlı, güvenilir bir şekilde ve bir değişiklik programı ile iletebilen, trafiğin her iki tarafında uzman teknik destek ve BT'ye sahip iki sistem arasında iletişim kurmak için dahili bir API yazıyorsanız, REST size hiçbir şey satın almaz. İhtiyacınız yok, uygulamanız yeterince büyük değil ve önemli olacak kadar uzun ömürlü değil.

Büyük kullanıcı tabanlarına sahip büyük sitelerde bu sorun var. Sistemleriyle etkileşime girerken insanlardan müşteri kodlarını bir hevesle değiştirmelerini isteyemezler. Sunucu geliştirme çizelgesi, istemci geliştirme çizelgesiyle aynı değildir. Her iki taraftaki trafiği ve işlemleri kesintiye uğrattığı için API'de ani değişiklikler, dahil olan herkes için kesinlikle kabul edilemez.

Bu nedenle, böyle bir işlem büyük olasılıkla HATEOAS'tan faydalanacaktır, çünkü sürümlemesi daha kolaydır, eski istemcilerin geçişi daha kolaydır, geriye dönük uyumluluğa sahip olmamasından daha kolaydır.

İş akışının çoğunu sunucuya devreten ve sonuçlara göre hareket eden bir istemci, sunucu değişikliklerine karşı bunu yapmayan bir istemciye göre çok daha güçlüdür.

Ancak çoğu insan bu esnekliğe ihtiyaç duymaz. 2 veya 3 departman için sunucu kodu yazıyorlar, hepsi dahili kullanım. Eğer kırılırsa, tamir ederler ve bunu normal işlemlerine dahil ettiler.

REST veya başka herhangi bir şeyden esneklik, karmaşıklığı doğurur. Basit ve hızlı istiyorsanız, o zaman onu esnek yapmazsınız, "sadece yaparsınız" ve bitirdiniz. Sistemlere soyutlamalar ve referansların kaldırılması ekledikçe, işler daha da zorlaşır, daha fazla kazan plakası, test edilecek daha fazla kod.

REST'in çoğu, "buna ihtiyacınız olmayacak" mermi noktasında başarısız oluyor. Tabii ki yapana kadar.

İhtiyacınız olursa, kullanın ve düzenlendiği gibi kullanın. REST, HTTP üzerinden ileri geri hareket etmiyor. Hiç olmadı, bundan çok daha yüksek seviyede.

Ancak REST'e ihtiyacınız olduğunda ve REST'i kullandığınızda, HATEOAS bir gerekliliktir. Paketin bir parçası ve onu işe yarayan şeyin anahtarı.


11
Bu cevap için en az bin tane daha beğenmen gerektiğini düşünüyorum. Dürüst olmak gerekirse, şunu hayal etmeliyim: 'Gerçek' olmak ne kadar önemli REST sorusu epeyce gündeme geliyor. Cehennem, bu konuyu bulduğumda yaklaşan bir toplantıda cephanenin kullanılması için sadece bu nedenle biraz googling yapıyordum.
nograde

2
Tanrıya şükür (veya kod), birisi HATEOAS'ın dezavantajlarından da bahsediyor!
IlliakaillI

6
URL'leri kolayca değiştirebilmenin başka bir avantajı var mı? Yeni seçenekler ekleyemezsiniz çünkü insanların aksine program yeni bir şeyle çalışamaz. Ayrıca, yalnızca URL'leri bilmek yerine eylemlerin adını bilmeye geçtiniz.
Jimmy T.

API tüketicisi hiçbir şey bilmiyorsa, yalnızca kullanıcı eylemlerini 1: 1'e devredebilir
Jimmy T.

2
URL'lerin değişikliğiyle ilgili olarak, istemcinizin önbellek kullanabileceğini unutmayın ve bu nedenle, önceki URL'yi işlemek için sunucuda davranışı korumanız gerekir (veya yalnızca yeniden yönlendirme yapın). API'leri geliştirmek için herhangi bir strateji olarak, eski davranışınızı devam ettirmelisiniz. HATEOAS orada pek yardımcı olmuyor.
Bruno Costa

21

Evet, API'lerde hiper medyayla ilgili bazı deneyimlerim oldu. Avantajlardan bazıları şunlardır:

  1. Keşfedilebilir API: Önemsiz gelebilir ancak keşfedilebilir bir API'nin gücünü küçümsemeyin. Verilere göz atma yeteneği, istemci geliştiricilerin API'nin ve veri yapılarının zihinsel bir modelini oluşturmasını çok daha kolaylaştırır.

  2. Satır içi dokümantasyon: URL'lerin bağlantı ilişkileri olarak kullanılması, istemci geliştiricilerini dokümantasyona yönlendirebilir.

  3. Basit istemci mantığı: URL'leri kendisi oluşturmak yerine yalnızca izleyen bir istemcinin uygulanması ve bakımı daha kolay olmalıdır.

  4. Sunucu, URL yapılarının sahipliğini alır: Hipermedya kullanımı, istemcinin sunucu tarafından kullanılan URL yapıları hakkındaki sabit kodlanmış bilgisini ortadan kaldırır.

  5. İçeriğin diğer hizmetlere yüklenmesi: İçeriği diğer sunuculara (örneğin bir CDN) aktarırken Hypermedia gereklidir.

  6. Bağlantılarla sürüm oluşturma: Hypermedia, API'lerin sürümlerinin belirlenmesine yardımcı olur.

  7. Aynı hizmetin / API'nin birden çok uygulaması: Hypermedia, aynı hizmetin / API'nin birden çok uygulaması mevcut olduğunda bir gerekliliktir. Bir hizmet, örneğin gönderi ve yorum eklemek için kaynaklar içeren bir blog API'si olabilir. Hizmet, sabit kodlanmış URL'ler yerine bağlantı ilişkileri açısından belirtilirse, aynı hizmet farklı URL'lerde birden çok kez somutlaştırılabilir, farklı şirketler tarafından barındırılır, ancak yine de tek bir müşteri tarafından aynı iyi tanımlanmış bağlantılar kümesi aracılığıyla erişilebilir.

Bu madde işaretlerinin ayrıntılı bir açıklamasını burada bulabilirsiniz: http://soabits.blogspot.no/2013/12/selling-benefits-of-hypermedia.html

(Burada benzer bir soru var: /software/149124/what-is-the-benefit-of-hypermedia-hateoas aynı açıklamayı verdiğim yerde)


Aynı hizmetin birden fazla uygulaması: detaylandırabilir misiniz? Nasıl yardımcı olacağını anlamıyorum.
Abbadon

Metinde açıklamaya çalıştım. Yardımcı olur mu?
Jørn Wildt

11

Richardson'un olgunluk düzeyi 3 değerlidir ve benimsenmelidir. Jørn Wildt bazı avantajları zaten özetledi ve Wilt'in verdiği başka bir cevap bunu çok iyi tamamlıyor.

Bununla birlikte, Richardson'un olgunluk seviyesi 3, Fielding'in HATEOAS'ı ile aynı değildir. Richardson'un olgunluk düzeyi 3 yalnızca API tasarımıyla ilgilidir. Fielding'in HATEOAS'ı da API tasarımı ile ilgilidir, ancak istemci yazılımının bir kaynağın ortam türü tarafından tanımlanan yapının ötesinde belirli bir yapıya sahip olduğunu varsaymaması gerektiğini de belirtir. Bu, belirli web siteleri hakkında bilgisi olmayan bir web tarayıcısı gibi çok genel bir istemci gerektirir. Roy Fielding, REST terimini icat ettiğinden ve HATEOAS'ı REST'e uyum için bir gereklilik olarak belirlediğinden, soru şudur: HATEOAS'ı benimsemek istiyor muyuz ve değilse, yine de API RESTful'umuzu arayabilir miyiz? Bence yapabiliriz. Açıklamama izin ver.

HATEOAS'a ulaştığımızı varsayalım. Uygulamanın istemci tarafı artık çok geneldir, ancak büyük olasılıkla kullanıcı deneyimi kötüdür, çünkü kaynakların anlambilimiyle ilgili herhangi bir bilgi olmadan, kaynakların sunumu bu anlambilimlerini yansıtacak şekilde uyarlanamaz. Kaynak 'araba' ve kaynak 'ev' aynı ortam türüne sahipse (örn. Uygulama / json), kullanıcıya aynı şekilde, örneğin bir özellikler tablosu (ad / değer çiftleri) olarak sunulacaktır.

Ama tamam, API'miz gerçekten RESTful.

Şimdi, bu API'nin üzerine ikinci bir istemci uygulaması oluşturduğumuzu varsayalım. Bu ikinci müşteri HATEOAS fikirlerini ihlal ediyor ve kaynaklar hakkında sabit kodlanmış bilgilere sahip. Bir araba ve bir evi farklı şekillerde gösterir.

API yine de RESTful olarak adlandırılabilir mi? Ben öyle düşünüyorum. İstemcilerinden birinin HATEOAS'ı ihlal etmesi API'nin hatası değildir.

RESTful API'leri, yani genel bir istemcinin teoride uygulanabileceği API'ler oluşturmanızı öneririm , ancak çoğu durumda, kullanılabilirlik gereksinimlerini karşılamak için istemcinizdeki kaynaklar hakkında bazı sabit kodlu bilgilere ihtiyacınız vardır. Yine de, istemci ve sunucu arasındaki bağımlılıkları azaltmak için olabildiğince az sabit kod yazmaya çalışın.

JAREST adlı REST uygulama modelime HATEOAS ile ilgili bir bölüm ekledim .


9

Yanıtımızın HAL-Json'da olduğu bir REST seviye 3 API oluşturuyoruz. HATEOAS hem ön hem de arka uç için harikadır ancak zorluklarla birlikte gelir. HAL-Json yanıtı (HAL-Json standardını bozmayan) içindeki ACL'yi yönetmek için bazı özelleştirmeler / eklemeler yaptık.

HATEOAS'ın en büyük avantajı, ön uç uygulamamızda herhangi bir url yazmamıza / tahmin etmemize gerek olmaması. İhtiyacınız olan tek şey bir giriş noktasıdır ( https://hostname) ve oradan, yanıtın içinde sağlanan bağlantıları veya şablonlu bağlantıları kullanarak kaynaklar arasında gezinmeniz yeterlidir . Bu sürüm oluşturma gibi kolayca işlenebilir, URL'leri yeniden adlandırabilir / değiştirebilir, kaynakları ön uç kodunu bozmadan ek ilişkilerle genişletebilir.

Kaynakların ön uçta önbelleğe alınması, öz bağlantıları kullanarak çocuk oyuncağıdır. Ayrıca, kaynakları bir soket bağlantısı aracılığıyla istemcilere de gönderiyoruz, çünkü bunlar da HAL'de işlendiğinden, onları aynı şekilde önbelleğe kolayca ekleyebiliriz.

HAL-Json kullanmanın bir başka avantajı, takip edilmesi gereken belgelenmiş bir standart olduğundan, yanıt modelinin neye benzemesi gerektiğinin açık olmasıdır.

Bizim özelleştirmelerin biri, bir eylem kendiliğinden bağlantı nesnesinin içinde itiraz ekledi olduğuna kimliği doğrulanmış kullanıcı, ilgili kaynakta gerçekleştirmesine izin verilen eylemler veya CRUD operasyonları ön ucuna İFŞA ( create:POST, read:GET, update:PUT, edit:PATCH, delete:DELETE). Bunun gibi, ön uç ACL'miz tamamen REST API yanıtımız tarafından belirlenir ve bu sorumluluğu tamamen arka uç modele taşır.

Hızlı bir örnek vermek gerekirse HAL-Json'da şuna benzer bir post nesnesine sahip olabilirsiniz:

{
    "_links": {
        "self": {
            "href": "https://hostname/api/v1/posts/1",
            "actions": {
                "read": "GET",
                "update": "PUT",
                "delete": "DELETE"
            }
        }
    },
    "_embedded": {
        "owner": {
            "id": 1,
            "name": "John Doe",
            "email": "john.doe@example.com",
            "_links": {
                "self": {
                    "href": "https://hostname/api/v1/users/1",
                    "actions": {
                        "read": "GET"
                    }
                }
            }
        }
    },
    "subject": "Post subject",
    "body": "Post message body"
}

Şimdi ön uçta tek yapmamız gereken, gerçekleştirmek istediğimiz eylemin eylemler nesnesinde olup olmadığını kontrol eden AclServicebir isAllowedyöntemle bir a oluşturmaktır .

Şu anda ön uçta şu kadar basit görünüyor: post.isAllowed('delete');

Bence REST seviyesi 3 harika, ancak bazı baş ağrılarına yol açabilir. REST konusunda çok iyi bir anlayışa sahip olmanız gerekecek ve 3. seviye REST ile çalışmak istiyorsanız REST konseptini kesinlikle takip etmenizi öneririm, aksi takdirde uygularken kolayca yolunuzda kaybolursunuz.

Bizim durumumuzda hem ön hem de arka uç oluşturmamız avantajına sahibiz, ancak prensipte bu bir fark yaratmamalı. Ancak ekibimizde gördüğüm yaygın bir tuzak, bazı geliştiricilerin arka uç modellerini ön uç ihtiyaçlarına "uyacak" şekilde değiştirerek ön uç sorunlarını (mimari) çözmeye çalışmasıdır.


1
Çok güzel cevap. Bence bu kadar pratik bir örnek, ilk sorgulayıcının aradığı şeydi.
www.admiraalit.nl

2

HATEOAS'ı bazı gerçek projelerde kullandım, ancak Richardson'dan farklı bir yorumla. Eğer patronlarının istediği buysa, sanırım bunu yapmalısın. HATEOAS'ı, kaynaklarınızın bir HTML belge türü, ilgili kaynaklara köprüler ve GET dışındaki fiillerin işlevselliğini ortaya çıkarmak için HTML formları içermesi gerektiği anlamına gelir. (Bu, Kabul türünün text / html olduğu zamandır - diğer içerik türleri bu ekstraları gerektirmez.) Tüm uygulamanızdaki tüm REST kaynaklarının birbirine yapıştırılması gerektiği inancının nereden geldiğini bilmiyorum. Bir ağ uygulaması, doğrudan ilişkili olabilecek veya olmayabilecek birden çok kaynak içermelidir. Veya neden XML, JSON ve diğer türlerin bunu izlemesi gerektiğine inanılıyor. (HATEOAS HTML'ye özgüdür.)

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.