REST Api neden Cephe tasarım desenini takip etmiyor?


9

REST yapısı ile bir OO modelinin karşılaştırılmasında şu benzerlikleri görüyorum:

Her ikisi de:

  • Veri odaklı mı

    • REST = Kaynaklar
    • OO = Nesneler
  • Verilerin etrafında surround çalışma

    • REST = Surround VERBS (Al, Gönder, ...)
    • OO = kapsülleme yoluyla nesnelerin etrafındaki işlemi teşvik

Bununla birlikte, örneğin cephe modelini uygulamaya çalışırken iyi OO uygulamaları her zaman REST API'leri üzerinde durmaz: REST'te, tüm istekleri işlemek için 1 denetleyiciniz yoktur VE dahili nesne karmaşıklığını gizlemezsiniz.

2 kavram arasında basit nesne ilişkisi

OO ve REST arasındaki benzerlik

Aksine, REST bir kaynakla ve diğerleriyle olan tüm ilişkilerin en az iki biçimde yayınlanmasını teşvik eder:

  1. Kaynak hiyerarşi ilişkileri yoluyla (43 numaralı bir kişi 454 numaralı bir adresten oluşur): /api/contacts/43/addresses/453

  2. bir REST json yanıtındaki bağlantılar aracılığıyla:

>> GET /api/contacts/43
<< HTTP Response {
   id: 43, ...
   addresses: [{
      id: 453, ...
   }],
   links: [{
      favoriteAddress: {
          id: 453
      }
   }]
}

ObjectA tarafından gizlenen temel karmaşıklık

OO'ya dönersek , cephe tasarım modeli Low Couplingbir objectA ile onun ' objectB istemcisi ' arasında ve High Cohesionbu objectA ve onun dahili nesne kompozisyonu ( objectC , objectD ) arasında bir a'ya saygı duyar . İle ObjectA arayüzünde, bu sınırı etkisiyle bir geliştirici izin objectB ait ObjectA (iç değişikliklere objectC ve objectD sürece,) ObjectA hala saygı API (operasyonlar).

REST'te, veriler (kaynak), ilişkiler (bağlantılar) ve davranış (fiiller) farklı öğelerde patlatılır ve web tarafından kullanılabilir.

REST ile oynamak, her zaman istemcim ve sunucu arasındaki kod değişiklikleri üzerinde bir etkisi var: Çünkü High Couplingbenim Backbone.jsistekleri Low Cohesionarasında ve kaynaklar arasında.

REST bağlantıları tarafından tanıtılan Backbone.js javascript application" REST kaynakları ve özellikleri " keşfi ile nasıl başa çıkabileceğimi asla anlayamadım . WWW'nin çoklu sunucular tarafından sunulması gerektiğini ve OO öğelerinin orada birçok ana bilgisayar tarafından hizmet verilmek üzere patlatılması gerektiğini, ancak adresleriyle bir kişiyi gösteren bir sayfayı "kaydetmek" gibi basit bir senaryo için, Ben sonunda:

GET /api/contacts/43?embed=(addresses)
[save button pressed]
PUT /api/contacts/43
PUT /api/contacts/43/addresses/453

bu da kaydetme eylemini tarayıcı uygulamalarında atom işlemsel sorumluluğunu taşımama yönlendiriyor (çünkü iki kaynak ayrı ayrı ele alınabilir).

Bunu göz önünde bulundurarak, gelişimimi basitleştiremezsem (Cephe tasarım desenleri geçerli değil) ve müşterime daha fazla karmaşıklık getirirsem (işlemsel atomik tasarruf işlemek), RESTful olmanın faydası nedir?


1
Anlamama izin ver. Bir Kişiyi, diğeri Adres için olmak üzere iki REST çağrısı kullanarak "katıştırılmış" (kompozisyon) bağlantılı adresli bir Kişiyi güncellemeniz gerektiğini söylüyorsunuz. Güncelleme kişilerini işlemek için bir Cepheniz var. PUT /api/contacts/43İç nesneler için güncellemeleri basamaklandırmayla ilgili sorun nedir ? Ben böyle tasarlanmış API bir sürü vardı (ana URL okur / oluşturur / "bütün" ve alt urls parçaları günceller). Hiçbir değişiklik gerekmediğinde (performans nedenleriyle) adresi güncellemediğinizden emin olun.
Anthony Accioly

@AnthonyAccioly, doğru anladın. Bazı resimler ekleyerek sorumu açıklığa kavuşturmaya çalıştım. Öneriniz iyi ve bu da birlikte geldiğim sonuç: isteğimi manuel olarak kontrol etmek ve atomik güncellememi tutmak için yalnızca bir istek göndermek için gömülü bir nesne kullanmak. Yine de: REST'teki her şey neden modelimi düzleştirerek (birçok denetleyiciyi ima ediyor) beni OO niteliklerinden veya yaptırımlarından (kapsülleme, ...) uzaklaştırıyor. Çözümünüzü kullanmak 1 atomik güncelleme sağlar. Çözümünüzü kullanmamak geliştiriciye yeni bir sorumluluk getirir ve bunu yapmasını önlemek için API'de hiçbir kural yoktur.
Alain

Sadece bir not: bahsettiğiniz "kaynak hiyerarşi ilişkileri", bir tanımlayıcıdaki (bu örnekte bir URL) ilişki bilgilerini nasıl kodlamaya karar verebileceğidir. Bu bilginin açığa çıkmasının REST'in bir parçası olduğu ya da teşvik ettiği bir şey olduğundan emin değilim, sadece bir sistemin URL'lerini ararken kendi başına bir karar verir. Aksini düşünüyorsanız, REST'in bir parçası olarak bu konuyu tartışan Roy Fielding referanslarınız var mı?
Thiago Silva

Yanıtlar:


7

Bence nesneler sadece doğru davranışlar etrafında oluşturulmuş, veriler etrafında değil. Provoke edeceğim ve verilerin nesne yönelimli dünyada neredeyse alakasız olduğunu söyleyeceğim. Aslında, hiç bir zaman veri döndürmeyen nesneler, örneğin "günlük havuzları" veya geçtikleri verileri hiçbir zaman döndürmeyen nesneler (örneğin, istatistiksel özellikler hesaplıyorlarsa) olması mümkündür.

Bize karıştırmayalım Pod'umuz (diğer yapılara göre daha küçük olan), ve (gibi davranışlara sahip gerçek nesneler Contactssizin örnekte sınıfın) 1 .

PODS temel olarak depolar ve iş nesneleriyle konuşmak için kullanılan bir rahatlıktır. Kodun tür güvenliğini sağlar. Ne fazla ne az. Öte yandan iş nesneleri, verilerinizi doğrulama veya depolama veya hesaplama yapmak için kullanma gibi somut davranışlar sağlar .

Bu nedenle, davranışlar "bütünlüğü" 2 ölçmek için kullandığımız şeydir ve yalnızca üst düzey kişileri işlemek için yöntemler göstermenize ve adresleri işlemek için hiçbir yöntem göstermemenize rağmen, nesne örneğinizde bir miktar uyum olduğunu görmek yeterince kolaydır.

REST ile ilgili olarak, REST hizmetlerini veri havuzları olarak görebilirsiniz. Nesneye yönelik tasarımdaki en büyük fark (neredeyse) sadece bir tasarım seçeneğinin olmasıdır: dört temel yönteminiz var ( HEADörneğin daha fazla sayıyorsanız) ve elbette URI'lerle çok fazla boşluğunuz var, böylece şık yapabilirsiniz gibi birçok şey geçmek ve daha büyük bir yapı geri almak. Karıştırmayın verileri onlar ile geçmek operasyonlar onlar gerçekleştirin. Uyum ve kuplaj veri ile değil kodla ilgilidir .

Açıkçası, REST hizmetleri yüksek bir kaynağa (bir kaynakla etkileşimde bulunmanın her yolu aynı yerdedir) ve düşük bağlantıya (her kaynak deposu diğerlerinin bilgisini gerektirmez) sahiptir.

Bununla birlikte, temel gerçek, REST'in aslında verileriniz için tek bir veri havuzu modelidir . Bunun sonuçları vardır, çünkü "sohbet" için yüksek bir maliyetin olduğu yavaş bir ortama göre kolay erişilebilirlik üzerine inşa edilmiş bir paradigmadır: müşteriler genellikle mümkün olduğunca az işlem yapmak ister, ancak aynı zamanda sadece ihtiyaç duydukları verileri alırlar . Bu, bir veri ağacının ne kadar geri göndereceğinizi belirler.

Nesne yönelimli (doğru) tasarımda, önemsiz olmayan herhangi bir uygulama, örneğin kompozisyon yoluyla çok daha karmaşık işlemler yapacaktır. Verilerle daha özel işlemler yapmak için yöntemleriniz olabilir - öyle olmalı, çünkü REST bir API protokolü olsa da, OOD, kullanıcılara yönelik tüm uygulamaları oluşturmak için kullanılır! Bu nedenle uyum ve bağlantının ölçülmesi OOD için temeldir, ancak REST'te neredeyse önemsizdir.

Şimdiye kadar açıktır ki, veri tasarımını OO konseptleriyle analiz etmek , onu ölçmenin güvenilir bir yolu değildir: elma ve portakalları karşılaştırmak gibi!

Aslında, RESTful olmanın faydalarının (çoğunlukla) yukarıda özetlenen faydaları olduğu ortaya çıkıyor: yavaş bir ortam üzerinde basit API'ler için iyi bir model. Çok önbelleğe alınabilir ve keskinleştirilebilir. Sohbet, vb üzerinde ince taneli kontrole sahiptir.

Umarım bu (çok yönlü) sorunuza cevap verir :-)


1 Bu sorun, Nesne İlişkisel empedans uyumsuzluğu olarak bilinen daha geniş bir sorun kümesinin parçasıdır . ORM'lerin taraftarları genellikle kampta veri analizi ve davranış analizi arasındaki benzerlikleri araştırıyorlar , ancak ORM'ler empedans uyumsuzluğunu gerçekten çözmedikleri ve sızdıran soyutlamalar olarak değerlendirildikleri için geç eleştirilere düştüler .

2 http://en.wikipedia.org/wiki/Cohesion_(computer_science)


Haklısın, sorumu birçok yönden patlatmak, belirli bir noktayı saptamak için zor zamanım vardı, çünkü soru bu yönlerin birikmesine dayanan "yanlış" bir sonuca hitap ediyor. Şimdi birçok yorumda puanlarınıza cevap vermeye çalışacağım.
Alain

[text 1] OO ve REST dünyasından soyutlamak için "data" kelimesini kullandım. OO'daki özellikleri ve REST'teki veri yapısını soyutlamak için hangi kelimeyi kullanırdınız?
Alain

@Alain "veri" iyi, ama benim açımdan PODS ve iş nesneleri karıştırmak değil. OOD hakkında konuştuğumuzda genellikle ikincisinden bahsediyoruz. Birincisi kolaylıktır ve neredeyse bir sözlük veya yapı veya demet düşünülebilir.
Sklivvz

Evet, katılıyorum, model kaydetmenin basit bir json yapısı kullandığı Backbone.js'yi kullanıyorum. Burada metin gerçek kodlama deneyimimi yansıtıyor.
Alain

[text 3] Bu benim için yeni. Uyumun belirli bir ilişki kullandığı zaman yöntemi ile ölçüldüğünü sanıyordum ... Bunu görüntüleme şeklinizi tercih ederim.
Alain

1

Bunu göz önünde bulundurarak, gelişimimi basitleştiremezsem (Cephe tasarım desenleri geçerli değil) ve müşterime daha fazla karmaşıklık getirirsem (işlemsel atomik tasarruf işlemek), RESTful olmanın faydası nedir?

"RESTful olmanın yararı nerededir?" burada ayrıntılı bir şekilde analiz edilmiş ve açıklanmıştır: http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm

Bu sorudaki karışıklık, bunun REST'in özellikleri ve onlarla nasıl başa çıkılacağı ile ilgili olmadığı, ancak örnek sisteminiz için bulduğunuz URL'lerin tasarımının RESTful ile ilgisi olduğu düşüncesidir. Sonuçta, REST, kaynak adı verilen şeyler olduğunu ve referans verilmesi gerekenler için bir tanımlayıcı sağlanmasını belirtiyor, ancak ER modelinizdeki varlıkların oluşturduğunuz URL'lerle 1-1 yazışmalarının olması gerektiğini belirtmiyor. (URL'lerin hiçbiri modeldeki ER ilişkilerinin önemini kodlamamalıdır).

Kişiler ve adresler söz konusu olduğunda, bu bilgileri, örneğin, farklı ilişkisel DB tablolarında PUT veya POSTed olduğunda ayıklamak ve kaydetmek isteseniz bile, bu bilgileri birlikte tek bir birim olarak temsil eden bir kaynak tanımlamış olabilirsiniz. .


1

Çünkü cepheler bir 'çamur'; 'api soyutlama' ve 'api zincirleme' konularına bir göz atmalısınız. API, iki işlevsellik kümesinin birleşimidir: G / Ç ve kaynak yönetimi. Yerel olarak, G / Ç gayet iyi ancak dağıtılmış bir mimari içinde (yani proxy, api geçidi, mesaj kuyruğu, vb.) G / Ç paylaşılıyor ve böylece veri ve işlevsellik kopyalanıyor ve dolanıyor. Bu, mimari bir kesişme endişesine yol açar. Bu TÜM mevcut apileri rahatsız ediyor.

Bunu çözmenin tek yolu, API için bir ön / son işleyiciye (İlkbahar / Grails'teki bir handlerIntercepter veya Rails'deki bir filtre gibi) G / Ç işlevlerini soyutlamaktır, böylece işlevsellik bir monad olarak kullanılabilir ve örnekler arasında ve harici olarak paylaşılabilir takım. İstek / yanıt verilerinin de bir nesnede dışa aktarılması gerekir, böylece paylaşılabilir ve yeniden yüklenebilir.

http://www.slideshare.net/bobdobbes/api-abstraction-api-chaining


0

REST hizmetinizi veya genel olarak herhangi bir API'yı anlarsanız, tıpkı istemcilere ek bir arabirim gibi , denetleyicilerinizi bu program aracılığıyla programlayabilmeleri için aniden kolaylaşır. Hizmet, biz mantığınızın üstünde ek bir katmandan başka bir şey değildir.

Başka bir deyişle, yukarıdaki mantığınızdaki gibi biz mantığını birden fazla denetleyici arasında bölmek zorunda değilsiniz ve daha da önemlisi, yapmamalısınız. Veri alışverişi için kullanılan veri yapılarının dahili olarak kullandığınız veri yapılarıyla eşleşmesi gerekmez, oldukça farklı olabilirler.

Herhangi bir biz mantığını UI koduna koymanın kötü bir fikir olması son teknoloji ürünüdür ve yaygın olarak kabul edilir. Ancak her kullanıcı arayüzü, arkasındaki mantığı kontrol etmek için sadece bir tür arayüzdür (kullanıcı arayüzündeki I). Sonuç olarak, REST hizmet katmanına veya herhangi bir API katmanına herhangi bir biz mantığı koymak da kötü bir fikirdir.

Kavramsal olarak, kullanıcı arayüzü ve hizmet API'si arasında çok fazla fark yoktur.


Katman kavramına katılıyorum, ama "kontrol cihazını programla" ile ne demek istiyorsun?
Alain

1
Denetleyicinin kendisinin gerçek hizmet olduğunu vurgulamak istiyorum. Her şeyin etrafına dolanan arayüz sadece bir şey elde etmenin bir yoludur. Bir şekilde veya başka bir şekilde, sarılmış işlevselliğe erişimi kolaylaştırmak için herhangi bir arabirim vardır. Bir GUI bunu insan kullanıcıları için yapar, istemciler tarafından bir hizmet API'si kullanılır. Her iki hedef kitle de arayüzün arkasındaki şeylerle bir şeyler başarmak istiyor. Kabul ediyorum "program" bunun için en iyi ifade olmayabilir, ama "kontrolörleri kontrol" ya da garip geliyor ;-)
JensG
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.