Czy klucze podstawowe bazy danych powinny być używane do identyfikowania jednostek w mikrousługach?
Biorąc pod uwagę, że mam dwie mikrousługi: Usługa A i Usługa B.
Usługa A jest właścicielem pełnych danych klienta, a Usługa B wymaga niewielkiego podzbioru tych danych (które pobiera z Usługi A, powiedzmy, poprzez ładowanie zbiorcze).
Obie usługi przechowują klientów we własnej bazie danych.
Jeśli usługa B musi następnie wejść w interakcję z usługą A, powiedz, aby uzyskać dodatkowe dane (np. GET / klienci / {id}), to wyraźnie potrzebuje unikalnego identyfikatora, który jest współdzielony między dwiema usługami.
Ponieważ identyfikatory są identyfikatorami GUID, mogę po prostu użyć PK z usługi A podczas tworzenia rekordu w usłudze B. Więc oba PK są zgodne.
Jednak brzmi to niezwykle krucho. Jedną z opcji jest przechowywanie „zewnętrznego identyfikatora” (lub „identyfikatora źródła”) jako oddzielnego pola w usłudze B i używanie go do interakcji z usługą A. Prawdopodobnie jest to ciąg znaków, ponieważ pewnego dnia może nie być identyfikatorem GUID.
Czy istnieje „najlepsza praktyka” w tym zakresie?
aktualizacja
Zrobiłem więc więcej badań i znalazłem kilka powiązanych dyskusji:
Czy należy ujawniać klucz podstawowy w adresach URL REST API?
Czy ujawnianie identyfikatora bazy danych klientowi w interfejsie API REST jest złą praktyką?
Ślimaki jako klucze główne
wniosek
Myślę, że mój pomysł, aby zachować oba Klucze Główne Klienta takie same w Usłudze A i B, był po prostu błędny. To dlatego, że:
- Najwyraźniej PK są specyficzne dla implementacji usługi, więc mogą być całkowicie niekompatybilne, np. UUID vs automatycznie inkrementowane INT.
- Nawet jeśli możesz zagwarantować kompatybilność, chociaż te dwa podmioty są nazywane „Klientami”, w rzeczywistości są to dwie (potencjalnie bardzo różne) koncepcje, a zarówno Usługa A, jak i Usługa B „posiadają” własne rekordy „Klienta”. Czego może chcieć zrobić chociaż jest zsynchronizować niektóre dane z klientami w tych usług.
Więc teraz myślę, że każda usługa może ujawniać dane klienta za pomocą własnego unikalnego identyfikatora (w moim przypadku PK GUID) i jeśli jedna usługa musi uzyskać dodatkowe dane klienta z innej usługi, musi przechowywać inny identyfikator / klucz usługi i używa go. Więc zasadniczo wracam do mojej idei „identyfikatora zewnętrznego” lub „identyfikatora źródła”, ale być może bardziej szczegółowego jako „identyfikator usługi B”.
Odpowiedzi
Myślę, że zależy to trochę od źródła danych i projektu. Ale jedyną rzeczą, której chciałbym unikać, jest klucz podstawowy, który jest identyfikatorem GUID lub automatyczną liczbą całkowitą do usługi zewnętrznej. To są wewnętrzne szczegóły Twojej usługi, a nie to, od jakich innych usług powinny zależeć.
Wolałbym mieć zewnętrzny identyfikator, który jest bardziej zrozumiały dla innych usług i być może dla całego biznesu. Może to być unikalny numer klienta, numer zamówienia lub numer polisy, a nie numer id
. Można je również traktować jako „identyfikator firmy”. Należy również pamiętać, że identyfikator zewnętrzny może być również ujawniony użytkownikowi końcowemu. W związku z tym jest to wszechobecny sposób identyfikacji tego „podmiotu” w całej organizacji i usługach, niezależnie od tego, czy masz projekt oparty na zdarzeniach, czy też usługi komunikują się przez interfejsy API. Ujawniłbym tylko identyfikatory DB w infrastrukturze lub repozytorium. Poza tym jest to tylko identyfikator biznesowy / zewnętrzny.
Cóż, jeśli masz pomysł na obiekt wartości, identyfikator biznesowy będzie znacznie lepszy do projektowania.
DDD koncentruje się na biznesie, czysty UUID / identyfikator automatycznego inkrementacji nie może go przedstawić.
Użyj identyfikatora biznesowego (UL ID), takiego jak identyfikator klienta, zamiast prostego identyfikatora.