Zamykanie maszyny wirtualnej za pośrednictwem interfejsu REST
To właściwie dość znany przykład, przedstawiony przez Tima Braya w 2009 roku .
Roy Fielding, omawiając problem, podzielił się spostrzeżeniem :
Osobiście wolę systemy, które traktują monitorowany stan (jak stan zasilania) jako nieedytowalny.
Krótko mówiąc, masz jeden zasób informacyjny, który zwraca bieżącą reprezentację monitorowanego stanu; reprezentacja ta może zawierać hipermedialny link do formularza , który żąda zmiany tego stanu, a formularz ma inne łącze do zasobu do obsługi (każdego) żądania zmiany.
Seth Ladd miał kluczowe informacje na temat problemu
Przekształciliśmy Bieg z prostego stanu osoby w prawdziwy Rzeczownik, który można tworzyć, aktualizować i mówić o nim.
Powrót do ponownego uruchamiania maszyn. Argumentowałbym, że zrobiłbyś POST na / vdc / 434 /uster / 4894 / server / 4343 / reboots Po wysłaniu masz identyfikator URI reprezentujący to ponowne uruchomienie i możesz go UZYSKAĆ w celu aktualizacji statusu. Dzięki magii hiperłącza reprezentacja ponownego uruchomienia jest połączona z ponownie uruchomionym serwerem.
Myślę, że wybijanie miejsca URI jest tanie, a URI są nawet tańsze. Utwórz zbiór działań, wzorowany na rzeczownikach, a następnie POST, PUT i DELETE!
RESTful programowanie to biurokracja Vogon na skalę internetową. Jak robisz cokolwiek RESTful? Wymyśl dla niego nowe formalności i zdigitalizuj formalności.
W nieco bardziej wyrafinowanym języku to, co robisz, to definiowanie protokołu aplikacji domeny dla „zamykania maszyny wirtualnej” i identyfikowanie zasobów, których potrzebujesz do ujawnienia / wdrożenia tego protokołu
Patrząc na własne przykłady
PATCH /api/virtualmachines/42
Content-Type:application/json
{ "state": "shutting down" }
W porządku; tak naprawdę nie traktujesz samego żądania jako osobnego zasobu informacyjnego, ale nadal możesz nim zarządzać.
Trochę przeoczyłeś swoją reprezentację zmiany.
Jednak w PATCH dołączona jednostka zawiera zestaw instrukcji opisujących, w jaki sposób zasób obecnie rezydujący na serwerze źródłowym powinien zostać zmodyfikowany w celu utworzenia nowej wersji.
Na przykład typ nośnika poprawki JSON formatuje instrukcje tak, jakbyś bezpośrednio modyfikował dokument JSON
[
{ "op": "replace", "path": "state", "value": "shutting down" }
]
Alternatywnie pomysł jest bliski, ale oczywiście nie poprawny. PUT
to całkowite zastąpienie stanu zasobu pod docelowym adresem URL , więc prawdopodobnie nie wybrałbyś pisowni, która wygląda jak kolekcja jako cel reprezentacji pojedynczej jednostki.
POST /api/virtualmachines/42/actions
Jest zgodny z fikcją, że dołączamy akcję do kolejki
PUT /api/virtualmachines/42/latestAction
Jest zgodny z fikcją, że aktualizujemy element ogona w kolejce; to trochę dziwne robić to w ten sposób. Zasada najmniejszego zaskoczenia zaleca nadanie każdemu PUT jego unikalnego identyfikatora, zamiast umieszczania ich wszystkich w jednym miejscu i modyfikowania wielu zasobów jednocześnie.
Zauważ, że w zakresie, w jakim omawiamy pisownię URI - REST nie ma znaczenia; /cc719e3a-c772-48ee-b0e6-09b4e7abbf8b
jest idealnie cromulent URI, jeśli chodzi o REST. Czytelność, podobnie jak w przypadku nazw zmiennych, stanowi odrębny problem. Używanie pisowni zgodnej z RFC 3986 sprawi, że ludzie będą znacznie szczęśliwsi.
CQRS
Co jeśli mamy domenę CQRS z wieloma takimi „działaniami” (inaczej komendami), które mogą potencjalnie prowadzić do aktualizacji wielu agregatów lub nie mogą być odwzorowane na operacje CRUD na konkretnych zasobach i pod-zasobach?
Greg Young w CQRS
CQRS to bardzo prosty wzorzec, który umożliwia wiele możliwości dla architektury, które w przeciwnym razie mogłyby nie istnieć. CQRS nie jest ostateczną spójnością, nie jest wydarzeniem, nie jest komunikatem, nie ma oddzielnych modeli do czytania i pisania, ani nie korzysta z pozyskiwania zdarzeń.
Kiedy większość ludzi mówi o CQRS, tak naprawdę mówi o zastosowaniu wzorca CQRS do obiektu reprezentującego granicę usługi aplikacji.
Biorąc pod uwagę, że mówimy o CQRS w kontekście HTTP / REST, rozsądne wydaje się założenie, że pracujesz w tym ostatnim kontekście, więc przejdźmy do tego.
Ten, co zaskakujące, jest jeszcze łatwiejszy niż twój poprzedni przykład. Powód tego jest prosty: polecenia to komunikaty .
Jim Webber opisuje HTTP jako protokół aplikacyjny biura z lat 50. XX wieku; praca jest wykonywana przez pobieranie wiadomości i umieszczanie ich w skrzynkach odbiorczych. Taki sam pomysł - otrzymujemy pustą kopię formularza, wypełnij go znanymi nam szczegółami, dostarcz go. Ta da
Czy powinniśmy próbować modelować tyle komend, ile konkretnych kreacji lub aktualizacji konkretnych zasobów, o ile to możliwe (zgodnie z pierwszym podejściem z przykładu I) i używać „punktów końcowych akcji” dla reszty?
Tak, o ile „konkretne zasoby” to komunikaty, a nie jednostki w modelu domeny.
Kluczowy pomysł: twój interfejs API REST wciąż jest interfejsem ; powinieneś być w stanie zmienić model bazowy bez potrzeby zmiany komunikatów przez klientów. Wydając nowy model, uwalniasz nową wersję internetowych punktów końcowych, które wiedzą, jak pobrać protokół domeny i zastosować go do nowego modelu.
Czy model CQRS lepiej pasuje do interfejsu API typu RPC?
Niezupełnie - w szczególności pamięci podręczne są doskonałym przykładem „ostatecznie spójnego modelu odczytu”. Umożliwiając niezależne adresowanie każdego z twoich widoków, każdy z własnymi regułami buforowania, daje ci możliwość skalowania za darmo. Stosunkowo mało pociąga podejście wyłącznie do RPC do czytania.
W przypadku zapisów jest to trudniejsze pytanie: wysłanie wszystkich poleceń do jednego modułu obsługi w jednym punkcie końcowym lub jednej rodzinie punktów końcowych jest z pewnością łatwiejsze . REST jest tak naprawdę bardziej o tym, jak znaleźć komunikację, gdzie punkt końcowy jest do klienta.
Traktowanie wiadomości jako własnego unikalnego zasobu ma tę zaletę, że można użyć PUT, ostrzegając komponenty pośredniczące o tym, że obsługa wiadomości jest idempotentna, aby mogli uczestniczyć w niektórych przypadkach obsługi błędów, miło jest mieć . (Uwaga: z punktu widzenia klientów, jeśli zasoby mają inny identyfikator URI, to są to różne zasoby; fakt, że wszystkie mogą mieć ten sam kod obsługi żądań na serwerze źródłowym, jest szczegółem implementacji ukrytym przez mundur berło).
Fielding (2008)
Powinienem również zauważyć, że powyższe nie jest jeszcze w pełni ODPOCZYNEK, przynajmniej jak używam tego terminu. Wszystko, co zrobiłem, to opis interfejsów serwisowych, który nie jest niczym więcej niż jakimkolwiek RPC. Aby uzyskać RESTful, musiałbym dodać hipertekst, aby wprowadzić i zdefiniować usługę, opisać, w jaki sposób wykonać mapowanie za pomocą formularzy i / lub szablonów linków, oraz dostarczyć kod do łączenia wizualizacji w użyteczny sposób.