TL; DR - Czy można współdzielić bibliotekę POJO między usługami?
Zasadniczo chcemy, aby dzielenie między usługami było ściśle ograniczone do żadnego, jeśli to możliwe. Odbyła się dyskusja, czy usługa udostępniająca dane powinna zapewniać bibliotekę klienta do użytku przez klientów. Klient-lib jest ogólnie opcjonalny dla klienta usługi i może korzystać z interfejsu API, jakkolwiek mu się podoba, czy używać klienta-lib, czy używać alternatywnego języka i korzystać z ogólnych aspektów biblioteki i tym podobnych.
W moim przypadku - uważam usługę, która tworzy obiekt danych. Załóżmy, że ten obiekt to PET. NIE jest to jednostka bazy danych, ale ściśle POJO, która pośrednio reprezentuje dane bazowe. To POJO zdefiniowało API. Załóżmy: zwierzę domowe - wiek, waga, imię, właściciel, adres, gatunek itp.
Usługa 1 - PetKeeper: Generuje zwierzaka z dowolnego powodu i zachowuje wszystkie dane i musi odwoływać się do tej usługi, aby uzyskać zwierzaka lub wprowadzić zmiany w zwierzaku, powiedzmy, że zmiana imienia lub zmiana adresu musi zostać wykonana za pomocą Wywołanie interfejsu API do tej usługi.
Usługa 2 - PetAccessor: Ta usługa zbiera zwierzaka i wykonuje kontrole walidacyjne
Usługa 3,4 - Więcej pośrednich połączeń serwisowych
Usługa 5 - interfejs użytkownika
Są to bardzo arbitralne, ale sprawa jest prosta. Interfejs użytkownika lub jakaś usługa skierowana do użytkownika chce w jakiś sposób przedstawić ten obiekt „PET”. Musi wywoływać za pośrednictwem interfejsu API usługę, która wywołuje usługę, która wywołuje usługę itp., Dopóki nie dotrze do usługi, która zbiera wymagane informacje i rozpoczyna przekazywanie z powrotem. Wreszcie usługa interfejsu użytkownika ma obiekt PET do wyświetlenia.
Jest to dość powszechne - ale przy naszej absolutnej mentalności duplikowaliśmy obiekt PET w każdej usłudze. Zasada DRY (nie powtarzaj się) dotyczy tylko kodu WEWNĄTRZ usługi i nie dotyczy wszystkich usług, ale kwestia nadal istnieje. Co jeśli dodamy pole ... musimy zmodyfikować po 5 usług POJO w każdym.
--LUB - Możemy zapewnić bibliotekę obiektów-zwierząt domowych, która zawiera niektóre pojęcia z interfejsu API, a każda usługa może importować / zależeć od biblioteki. Nie ma zależności od samych usług, ale tylko od biblioteki ogólnej. Podoba mi się ten pomysł, dzięki czemu każda usługa ma ten sam typ obiektu, a aktualizacje są łatwiejsze. Ale martwię się o Boskie Przedmioty.
Jakie są zalety / wady - jaki jest najlepszy projekt? Co zrobiłeś, aby przesyłać dane między usługami, aby zminimalizować powtarzanie tych samych klas POJO, jednocześnie pozostając rozłączonym?
źródło
Odpowiedzi:
Możesz ponownie użyć tego samego obiektu
Pet
DTO wśród usług zaplecza (które przetwarzają typową logikę biznesową), ale jeśli chodzi o warstwę prezentacji (interfejs użytkownika), ogólnie dobrą praktyką jest użycie FormBean (innej fasoli z dodanymi polami) dla logiki prezentacji), dzięki czemu będzie wyraźne oddzielenie logiki prezentacji od logiki biznesowej .Jest to wymagane, ponieważ usługi powinny być wielokrotnego użytku, a pojedyncza usługa może być ujawniona / ponownie wykorzystana przez wiele / różnych punktów końcowych (takich jak interfejs użytkownika lub może to być inna usługa internetowa itp.), A każdy z tych punktów końcowych może wymagać dodatkowych pól, które zostaną wypełnione przez odpowiednie Kontrolery lub warstwy (takie jak adaptery) nad usługami.
Jeśli używasz pojedynczego komponentu bean między warstwami biznesowymi i sieciowymi, to ściśle łączysz logikę prezentacji z logiką biznesową, co nie jest dobrą praktyką, i ostatecznie zmienisz usługi dla wymagań w interfejsie użytkownika (np. Inny format daty do wyświetlenia w interfejsie użytkownika). Ponadto, aby ten proces zapełniania / kopiowania danych między komponentami bean (np. DTO do FormBean lub Viceversa), można użyć bibliotek takich jak Apache
BeanUtils.copyProperties()
lub Dozer, aby uniknąć kodu płyty zbiorczej .źródło
PetServices
aby uniknąć powielania. Ale moim celem nie jest ścisłe połączenie zaplecza i interfejsu, to wszystko.Jeśli DTO reprezentuje ten sam podmiot gospodarczy we wszystkich mikrousługach, powinna istnieć tylko jedna klasa, dzielona między usługi. Duplikat kodu dla tego samego obiektu (prawie) nigdy nie jest poprawny.
źródło
Teraz planuję to zrobić tak, że każda usługa pakuje tylko DTO i umieszcza je w Nexusie jako jar lib. Gdy inne usługi będą tego potrzebować, dostaną te DTO lib (s) jako zależność w manve / gradle. Jeśli nowa wersja DTO zostanie wydana w jednej usłudze, będzie obowiązywać, dopóki stara wersja będzie również obsługiwana w tym samym czasie, więc nie naruszaj kompatybilności wstecznej, wersjonowania itp., Więc jest to obszar backend-to-backend. Aby zapobiec uzależnieniu od sieci, lepiej jest oddzielić usługę od pakowania Dto
Teraz spójrz na backend-to-frontend i vice versa Nie zgadzam się z poprzednimi komentarzami, że interfejs użytkownika jako warstwa prezentacji jest inna. NIE JEST!!! Interfejs użytkownika jest dla mnie kolejną mikrousługą, która również zużywa i wytwarza zdarzenia.
Kierunek backend-to-frontend To, co robię, to konwersja POJO (dtos) na interfejsy maszynopisu i pakowanie w NPM i ładowanie ich również do Nexusa. Projekt oparty na interfejsie użytkownika nodejs następnie je wykorzystuje i wykorzystuje. Jest to sposób obsługi interfejsu użytkownika.
Kierunek frontend -backend Aby interfejs użytkownika obsługiwał zdarzenia warstwy, konwertuję interfejsy maszynopisu i konwertuję je na POJO (dtos), pakuję jako jar i przesyłam do Nexusa (lub repozytorium) w postaci jar przeznaczonej do użytku przez usługi backendu.
Procesy te są łatwo obsługiwane przez procesy CI (Travis, Gitlab CI itp.)
Wszelkie uwagi dotyczące tego podejścia są mile widziane.
źródło