Próbuję zaprojektować aplikację, która ma złożoną domenę biznesową i wymaga obsługi interfejsu API REST (nie tylko REST, ale zorientowana na zasoby). Mam problem z wynalezieniem modelu domeny w sposób zorientowany na zasoby.
W DDD klienci modelu domeny muszą przejść przez warstwę procedur „Application Services”, aby uzyskać dostęp do dowolnej funkcji biznesowej, wdrożonej przez Entities i Domain Services. Na przykład istnieje usługa aplikacji z dwiema metodami aktualizacji encji użytkownika:
userService.ChangeName(name);
userService.ChangeEmail(email);
Interfejs API tej usługi aplikacji udostępnia polecenia (czasowniki, procedury), a nie stan.
Ale jeśli musimy również dostarczyć interfejs API RESTful dla tej samej aplikacji, istnieje model zasobów użytkownika, który wygląda następująco:
{
name:"name",
email:"email@mail.com"
}
Zorientowany na zasoby interfejs API udostępnia stan , a nie polecenia . Rodzi to następujące obawy:
każda operacja aktualizacji interfejsu API REST może być odwzorowana na jedno lub więcej wywołań procedur usługi aplikacji, w zależności od tego, jakie właściwości są aktualizowane w modelu zasobów
każda operacja aktualizacji wygląda jak atomowa dla klienta REST API, ale nie jest tak zaimplementowana. Każde wywołanie usługi aplikacji jest zaprojektowane jako osobna transakcja. Aktualizacja jednego pola w modelu zasobów może zmienić reguły sprawdzania poprawności dla innych pól. Musimy więc zweryfikować wszystkie pola modelu zasobów razem, aby upewnić się, że wszystkie potencjalne wywołania usługi aplikacji są prawidłowe, zanim zaczniemy je tworzyć. Sprawdzanie poprawności zestawu poleceń jednocześnie jest o wiele mniej trywialne niż wykonywanie pojedynczych poleceń. Jak to robimy na kliencie, który nawet nie wie, że istnieją poszczególne polecenia?
wywoływanie metod usługi aplikacji w innej kolejności może mieć inny efekt, a interfejs API REST sprawia, że wygląda na to, że nie ma różnicy (w ramach jednego zasobu)
Mógłbym wymyślić więcej podobnych problemów, ale w zasadzie wszystkie one są spowodowane przez to samo. Po każdym wywołaniu usługi aplikacji zmienia się stan systemu. Zasady obowiązującej zmiany, zestaw działań, które jednostka może wykonać następną zmianę. Zorientowany na zasoby interfejs API stara się, aby wszystko wyglądało jak operacja atomowa. Ale złożoność przekroczenia tej luki musi gdzieś zniknąć i wydaje się ogromna.
Ponadto, jeśli interfejs użytkownika jest bardziej zorientowany na polecenia, co często ma miejsce, będziemy musieli odwzorować polecenia i zasoby po stronie klienta, a następnie ponownie po stronie interfejsu API.
Pytania:
- Czy cała ta złożoność powinna być obsługiwana przez (grubą) warstwę odwzorowania REST na AppService?
- A może brakuje mi czegoś w rozumieniu DDD / REST?
- Czy REST może po prostu być niepraktyczny do ujawnienia funkcjonalności modeli domen w pewnym (dość niskim) stopniu złożoności?