Proponuję zmiany w bardzo źle zaprojektowanym projekcie oprogramowania, który ma wiele problemów. Na wysokim poziomie projekt wykorzystuje Angular na interfejsie i zużywa różne interfejsy API REST; co jest świetne (nie widzę potrzeby zmiany naszej technologii ani narzędzi). Problem polega na tym, że podstawa kodu jest nieproporcjonalnie większa w interfejsie użytkownika niż interfejsy API po stronie serwera. Znaczna część logiki biznesowej znajduje się w interfejsie użytkownika, przy czym interfejsy API REST są prostymi interfejsami bazy danych CRUD z warstwą interfejsu użytkownika.
Na przykład POST do klienta utworzy rekord klienta, a PUT zmodyfikuje tego klienta. Niewiele więcej i niewiele mniej. Nasza logika biznesowa jest jednak bardziej wymagająca. Ogólny proces tworzenia klienta robi znacznie więcej niż wstawianie 1 rekordu bazy danych. Dostarczy dane w innych niezbędnych tabelach, wykona pewne walidacje i obliczenia itp. Wolałbym wykonać pojedyncze wywołanie POST / PUT, które zawiera wszystkie te zachowania, zmniejszając obciążenie klienta konsumującego.
Dlatego uważam, że ta nadrzędna aranżacja powinna znajdować się na serwerze (gdzie mamy pełną kontrolę, dzienniki itp.), A nie w interfejsie użytkownika, ale jednym kontrargumentem jest to, że takie podejście nie byłoby już RESTful. Nie jestem więc pewien, jak najlepiej opisać to podejście, gdy zalecam kontynuowanie istniejącego stosu technologii, ale zaimplementuj podstawowe zmiany w lokalizacjach, do których należy kod.
źródło
Odpowiedzi:
Service oriented architecture
.Proponujesz przeprojektować system, aby reguły biznesowe i dane znajdowały się w tym samym miejscu. To faktycznie jest definicja usługi ; patrz wykład Udi Dahana na temat Finding Service Granice .
Pasek boczny: jak zauważył Eric, nie ma to nic wspólnego z „REST”. Nie ma absolutnie żadnego powodu, dla którego nie można umieścić interfejsu API REST (czyli interfejsu API, który spełnia ograniczenia stylu architektonicznego REST ) przed usługą. Ale może to nie być oczywiste dla osób, które rozumieją REST jako mapowanie operacji bazy danych na metody HTTP.
Warto inwestować w zmianę zrozumienia REST przez odbiorców.
źródło
REST nie jest CRUD. Ten „kontrargument” opiera się na zasadniczo błędnym zrozumieniu tego, czym jest REST. Nie widziałem w poście nic, co wskazywałoby, że zmiana spowodowałaby, że interfejs API byłby mniej lub bardziej RESTful.
źródło
Jeszcze jedną rzeczą, o której należy pamiętać ... Nie sprawdzanie poprawności strony serwera reguł biznesowych oznacza, że domyślnie ufasz wszystkim, co się pojawi, np. Przez żądanie POST, jest prawidłowe.
Oznacza to, że na przykład, podczas gdy twoja aplikacja kątowa może sprawdzić, czy klient ma prawidłowy przedział wiekowy i zapewnia, że uprawnieni użytkownicy otrzymają prawidłową informację zwrotną, każdy, kto zna adres URL twojego interfejsu API, może wykonać żądanie POST zawierające niektóre nieuzasadnione wartości, które mogłyby nie będzie już sprawdzany.
Tak więc moją propozycją byłoby przeniesienie reguł biznesowych do interfejsu API, pozwolenie na sprawdzenie poprawności danych wejściowych i zwrócenie odpowiednich błędów (a może tylko kodów wskazujących, co poszło nie tak) w treści odpowiedzi. Kody te można następnie wykorzystać w aplikacji front-end do wskazania, co poszło nie tak.
źródło
Aby dodać do innych dobrych odpowiedzi tutaj:
Interfejs, REST lub inny, nie powinien być ograniczony w oparciu o pewne założenia dotyczące szczegółów implementacji. Jest to całkowicie sprzeczne z pojęciem usług jako warstwy abstrakcji.
Jedną z głównych zalet korzystania z usług jest to, że szczegóły implementacji można zmieniać bez potrzeby wykonywania jakichkolwiek czynności przez klientów. Z tego, co opisałeś, wygląda na to, że nie ma prawdziwej warstwy abstrakcji. Szczegóły implementacji zostały ujawnione przez HTTP. Nic w REST nie mówi, że jest to konieczne, pomocne lub pożądane. W rzeczywistości wydaje mi się, że mógłbym argumentować pewne części definicji REST, aby oznaczać, że jest to w rzeczywistości implementacja bez RESTful.
Sugerujesz, jak zaprojektować odpowiednią warstwę usług. Jeśli ktoś mówi ci, że nie możesz tego zrobić, ponieważ nie jest to ODPOCZYNEK, to niefortunne. Możesz być pewien, że ktoś, kto ci powie, że niewiele wie nic o REST.
W oparciu o twoje pytanie masz zasób o nazwie klient. Wszystko i wszystko, co jest wymagane do utworzenia prawidłowego zasobu klienta, może i powinno być obsługiwane w
POST
zasobie podstawowym klienta (lub alternatywnie / opcjonalnie w PUT do określonego zasobu klienta, jeśli nie istnieje). REST nie mówi nic o tym, ile rekordy bazy danych, które należy utworzyć dla danego połączenia. Jak zauważył Colin Young, w ogóle nie musi istnieć baza danych, nie ma znaczenia, w jaki sposób usługi są wdrażane z perspektywy REST.źródło
Jest tu kilka dobrych odpowiedzi, ale nie jestem pewien, czy pomogą ci przekonać współpracowników. Jak wielu zauważyło, to, co sugerujesz, nie jest odejściem od RESTful design i myślę, że jest to kluczem do włączenia ich w twoją propozycję.
REST nie polega na upewnieniu się, że interfejs API pozwala tylko na przechowywanie i pobieranie danych. Raczej dotyczy działań modelowania jako zasobów. Twój interfejs API powinien umożliwiać podejmowanie działań (w końcu jest to interfejs programowania aplikacji ). Pytanie brzmi, jak modelować te działania.
Zamiast wymyślić termin, przykłady są prawdopodobnie najlepszym sposobem na wyjaśnienie tego swoim współpracownikom . W ten sposób możesz pokazać, jak oni to robią teraz, jakie problemy to powoduje, rozwiązanie, które rozwiązuje problem i jak nadal pozostaje ODPOWIEDZIALNY.
Spójrzmy na obiekt klienta.
Problem:
Interfejsy użytkownika POST klienta, ale kolejne tabele nie zostały jeszcze zaktualizowane. Co się stanie, jeśli jedno z kolejnych wywołań nie powiedzie się z powodu błędu w kodzie interfejsu użytkownika (lub nieprawidłowo działającej wtyczki przeglądarki itp.)? Teraz Twoje dane są niespójne. Może to być nawet stan, który psuje inne części interfejsu API lub interfejsu użytkownika, nie wspominając już o tym, że jest po prostu nieprawidłowy. Jak się odzyskujesz? Będziesz musiał przetestować każdy możliwy stan, aby upewnić się, że to niczego nie zepsuje, ale trudno byłoby wiedzieć, co jest możliwe.
Rozwiązanie:
Utwórz punkt końcowy interfejsu API, aby utworzyć klientów. Wiesz, że nie chcesz mieć punktu końcowego „/ customer / create”, a nawet „/ create-customer”, ponieważ create jest czasownikiem i naruszy REST. Więc dopracuj to. „/ tworzenie-klientów” może działać. Teraz, kiedy opublikujesz swój obiekt CustomerCreation, wyśle on wszystkie potrzebne pola, aby klient mógł zostać w pełni utworzony. Punkt końcowy zapewni, że dane są kompletne i poprawne (zwracając wartość 400 lub coś, jeśli nie powiedzie się sprawdzanie poprawności) i może na przykład zachować wszystko w ramach jednej transakcji db.
Jeśli potrzebujesz również punktu końcowego do GET / obiektów klientów, to w porządku. Możesz mieć oba. Sztuką jest tworzenie punktów końcowych, które spełniają potrzeby konsumentów.
Zalety:
Niedogodności:
Ludziom może być trudno zrozumieć ten paradygmat i co w nim dobrego, jeśli go nie wypróbowali. Mamy nadzieję, że możesz pomóc im zobaczyć, korzystając z przykładu z własnego kodu.
Moje własne doświadczenie jest takie, że gdy deweloperzy w moim zespole zaczęli wdrażać tę strategię, prawie natychmiast dostrzegli korzyści.
Dalsze badanie:
Ten artykuł z thinktworks naprawdę pomógł mi zrozumieć modelowanie działań jako obiektów na praktycznych przykładach: https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling
Sugerowałbym również przeczytanie o CQRS i zaopatrzeniu w zdarzenia, ponieważ dotyczą one właśnie tego rodzaju rzeczy (tj. Oddzielenie interfejsu API od rzeczywistej logiki trwałości). Nie wiem, jak chętni byliby twoi współpracownicy, aby czytać tego rodzaju rzeczy, ale może to dać ci większą jasność i pomóc ci to wyjaśnić.
źródło