Sunucu ve istemci arasında bir arayüz paylaşmak neden bu kadar kötü bir fikir?


12

Bir HTTP sunucusu ve istemcisi arasında bir arayüz paylaşmanın bir yolunu öğrendiğimde Spring Cloud Netflix belgelerini okuyordum . Genel HTTP iletişimine genişletilmemesinin bir nedeni olmamasına rağmen, bu örneği mikro hizmetler için kullanırlar:

// The shared interface, in a common library
public interface UserService {
    @RequestMapping(method = GET, value = "/users/{id}")
    User getUser(@PathVariable long id);
}

// The controller, on the server
@RestController
public class UserResource implements UserService {
}

// The same interface used for the client
@FeignClient("users")
public interface UserClient extends UserService {
}

Bu, hem sunucu (Bahar @RestControlleronu HTTP sunucusuna dönüştürür) hem de istemci (Feign @FeignClient, HTTP istemcisi kullanımı için ayarlar ) olarak kullanılan bir arabirimi tanımlar . Sunucu ve istemci sınıfı uygulamaları ayrı projelerde kullanılabilir, ancak türlerin eşleştiğinden emin olmak için aynı arabirimi kullanır.

Bununla birlikte, örneğin altına aşağıdaki uyarıyı koyuyorlar:

Not: Genellikle bir sunucu ile istemci arasında bir arayüz paylaşılması önerilmez. Sıkı bağlantı sağlar ve ayrıca Spring MVC ile şu anki haliyle çalışmaz (yöntem parametre eşlemesi kalıtsal değildir).

Tamam, bu yüzden şu anda iyi entegre değil ... ama bu bölüm, kodun paylaşılması ve sunucu ile istemci arasında daha önemli olduğunu düşündükleri bağlantıyı tanıtmaya yönelik uyarıdan sonra geliyor . Bir arayüzü bu şekilde paylaşmanın neden bu kadar kötü bir fikir olduğunu düşünüyorlar?

Bu olmadan, sunucu ve istemcinin birbirlerine anlayabilecekleri verileri göndermelerini garanti etme yeteneğini kaybedersiniz. Birine alan ekleyebilir ancak diğerini ekleyebilir ve yalnızca çalışma zamanına kadar uyumsuzluğu keşfedebilirsiniz. Benim fikrime göre, bu kuplajı tanıtmak değil , sadece zaten var olan kuplajı ortaya çıkarmaktır. Sunucuları tamamen bağımsız hale getirme ihtiyacı, ne tür veriler alacaklarını bildirme ihtiyacından daha mı fazla?


1
İstemciler / sunucular tarafından işlenen veri / biçimlendirme açısından var olan bağlantı, bir kural olarak kullanılabilecek bir belge olan protokol tarafından belirlenir . Bir arabirimi paylaşarak tanıtılan bağlantı bir derleme zamanı bağlantısıdır - arabirim değiştirildiğinde (örneğin geriye dönük olarak uyumsuz bir şekilde) ne olacağını düşünün, ancak bu arabirimi kullanan istemci / sunucu kodu farklı zamanlarda konuşlandırılır. Bu dağıtım zamanı bağlantısının, özellikle Netflix ölçeğinde yönetilmesi daha zor olabilir.
Castaglia

1
Netflix'in ölçeğinde çalışmadığımdan eminim :) ancak arayüzler geriye dönük olarak uyumsuz bir şekilde değiştirilirse, bu sadece hatayı derleme zamanında bulunmasından çalışma zamanında bulunmaya kaydırmaz mı? Tüm sunucuları yavaşça yükseltirken birkaç işlev çağrısının başarısız olmasına izin vermeyi düşünüyorlar mı?
Ben S

1
Muhtemelen; istemci koduna bağlıdır. Diğer durumu da göz önünde bulundurun: önce sunucular yükseltilir ve istemciler artık (beklenmedik bir şekilde) başarısız aramalarla uğraşmak zorunda kalırlar ...
Castaglia

1
Sadece merak ediyorum, bu arayüzü paylaşarak, istemciyi hangi dillerde / yığını oluşturabileceğinizi sınırlıyor mu?
JeffO

Evet - bu bir Java dosyasıdır, bu yüzden Java'yı kullanmanız gerekir. Sen olabilir başka JVM dil kullanmak mümkün ama bunu denemedim.
Ben S

Yanıtlar:


6

Yorumlarda belirtildiği gibi, bunun istemci platformunuzu sunucu platformunuza sıkıca bağlamasıyla sonuçlanmasıdır. Burada, sunucunuzun beklenen sözleşmesini anlamak için müşterinizin sunucuda kullandığınız dili / platformu kullanması gerektiği anlamına gelir. Aynı kodu (belirli bir dilin / platformun eseri) paylaşma ile belirli bir sözleşmeyi kabul etme arasında bir fark olduğunu unutmayın.

Birçok proje, sözleşmeleri için belgeleri kullanır. Standart protokoller (örn. REST) ​​üzerinden tarafsız formatta (örn. JSON) örnek istek ve yanıtlar. ( Örneğin Stripe API dokümanlarına bakın ). Kullanmak veya izin vermek isteyebileceğiniz her olası müşteri platformu için kod tabanlı bir sözleşme yazmak pratik olmadığından. Diğerleri ise tarafsız sözleşmeleri tanımlamak için API yönetim araçlarını kullanıyor .

Alan ekleme örneğiniz ayrı bir endişe kaynağıdır - sürüm API sözleşmelerinin neden önemli olduğunun bir örneği. İstemcilerin tasarlandıkları sürümü kullanmasına izin verin. Eskisinin yanında geriye dönük uyumsuz yeni bir API sürümü var. Eski sürümün istemcisi, ekibi güncellemeye gelene kadar veya siz eski sürümü kullanımdan kaldırılana kadar (kullanımdan kaldırma / taşıma döneminden sonra) çalışmaya devam eder. Bkz. Paralel Değişiklik .

Uyarısındaki (üstü kapalı tavsiye) uyarıyı takip etmek, istemci ve sunucunun her biri için anlamlı olan şekil ve hızlarda gelişmesine yardımcı olur. Sunucunuzun ve istemcinizin her zaman aynı dili / platformu paylaşacağını ve aynı hızda gelişeceğini makul bir şekilde garanti ederseniz, sözleşmenizle ilgili dile ve platforma özgü bir kod artefaktının kullanılması muhtemelen tamam olacaktır. Bununla birlikte, bu özellikle Netflix OSS'yi (özellikle bulut ölçeklenebilirliği ve performansı için özel olarak tasarlanmış, gerekli tüm karmaşıklığa sahip bir şey) hedefleyen projeler için makul bir beklenti değildir.


2
İstemcinin gerçekten arayüzü kullanması bekleniyor mu? Bu tür yapıları her zaman bir müşteri yazmayı kolaylaştırmanın bir yolu olarak gördüm. Sonuçta bir REST istemcisini farklı bir dilde yazabilirsiniz.
Jimmy T.

1
Tam olarak, api, rota tanımlarıyla, başka bir dilde bir müşterinin oluşturulmasını engelleyecek hiçbir şey olmayacak, ancak java kullandığınız sürece arayüzü kullanabilir
Leonardo Villela
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.