W jaki sposób interfejs API REST pasuje do domeny opartej na poleceniach / działaniach?

24

W tym artykule autor twierdzi, że

Czasami wymagane jest ujawnienie operacji w interfejsie API, która z natury nie jest w stanie RESTful.

i to

Jeśli interfejs API ma zbyt wiele działań, oznacza to, że albo został zaprojektowany z punktu widzenia RPC, a nie z wykorzystaniem zasad RESTful, lub że dany interfejs API jest naturalnie lepiej dopasowany do modelu typu RPC.

Odzwierciedla to, co czytałem i słyszałem także w innych miejscach.

Uważam to jednak za dość mylące i chciałbym lepiej zrozumieć tę sprawę.

Przykład I: Wyłączanie maszyny wirtualnej za pośrednictwem interfejsu REST

Są, moim zdaniem, dwa zasadniczo różne sposoby modelowania zamknięcia maszyny wirtualnej. Każda droga może mieć kilka odmian, ale na razie skupmy się na najbardziej fundamentalnych różnicach.

1. Popraw właściwość stanu zasobu

PATCH /api/virtualmachines/42
Content-Type:application/json  

{ "state": "shutting down" }

(Alternatywnie, PUTw podrzędnym zasobie /api/virtualmachines/42/state).

Maszyna wirtualna zostanie wyłączona w tle, a w późniejszym czasie, zależnie od tego, czy wcześniejsze zamknięcie zakończy się powodzeniem, czy nie, stan może zostać wewnętrznie zaktualizowany po wyłączeniu zasilania.

2. PUT lub POST we właściwości akcji zasobu

PUT /api/virtualmachines/42/actions
Content-Type:application/json  

{ "type": "shutdown" }

Wynik jest dokładnie taki sam jak w pierwszym przykładzie. Stan zostanie natychmiast zaktualizowany do „wyłączenia”, a być może do „wyłączenia”.

Czy oba projekty są RESTful?

Który projekt jest lepszy?

Przykład II: 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?

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?

Czy też powinniśmy odwzorować wszystkie polecenia na punkty końcowe akcji (jak w drugim podejściu z przykładu I)?

Gdzie powinniśmy narysować linię? Kiedy projekt staje się mniej ODPOWIEDNI?

Czy model CQRS lepiej pasuje do interfejsu API typu RPC?

Zgodnie z cytowanym tekstem powyżej jest to, jak rozumiem.

Jak widać z wielu moich pytań, jestem trochę zdezorientowany w tym temacie. Czy możesz mi pomóc lepiej to zrozumieć?

leifbattermann
źródło
„tworzenie akcji” nie wydaje się RESTfulowane, z wyjątkiem sytuacji, gdy wykonana akcja ma swój własny identyfikator zasobu. W przeciwnym razie zmiana właściwości „state” za pomocą PATCH lub PUT ma sens. Jeśli chodzi o część CQRS, nie mam jeszcze dobrej odpowiedzi.
Fabian Schmengler,
3
@Laiv Nie ma w tym nic złego. To pytanie akademickie, chciałbym lepiej zrozumieć tę sprawę.
leifbattermann

Odpowiedzi:

19

W pierwszym przypadku (zamknięcie maszyn wirtualnych) nie rozważałbym żadnej z alternatywnych metod operacyjnych jako RESTful. Oczywiście, jeśli użyjesz modelu dojrzałości Richardsona jako miernika, oba są interfejsami API co najmniej 2, ponieważ używają zasobów i czasowników.

Żadne z nich jednak nie używa kontrolek hipermedialnych i moim zdaniem jest to jedyny typ REST, który odróżnia projekt interfejsu API RESTful od RPC. Innymi słowy, trzymaj się poziomu 1 i 2, a w większości przypadków będziesz mieć interfejs API w stylu RPC.

Aby modelować dwa różne sposoby wyłączania maszyny wirtualnej, odsłoniłbym samą maszynę wirtualną jako zasób, który (między innymi) zawiera łącza:

{
    "links": [{
        "rel": "shut-down",
        "href": "/vms/1234/fdaIX"
    }, {
        "rel": "power-off",
        "href": "/vms/1234/CHTY91"
    }],
    "name": "Ploeh",
    "started": "2016-08-21T12:34:23Z"
}

Jeśli klient chce zamknąć Ploehmaszynę wirtualną, powinien skorzystać z łącza z shut-downtypem relacji. (Zwykle, jak opisano w książce RESTful Web Services Cookbook , możesz użyć IRI lub bardziej rozbudowanego schematu identyfikacji dla typów relacji, ale postanowiłem, aby przykład był tak prosty, jak to możliwe).

W takim przypadku akcji jest niewiele, dlatego klient powinien po prostu wykonać pusty test POST względem adresu URL w href:

POST /vms/1234/fdaIX HTTP/1.1

(Ponieważ to żądanie nie ma treści, pokusa byłoby modelować to jako żądanie GET, ale żądania GET nie powinny mieć żadnych obserwowalnych skutków ubocznych, więc test POST jest bardziej poprawny.)

Podobnie, jeśli klient chce wyłączyć maszynę wirtualną, power-offzamiast tego podąży za linkiem.

Innymi słowy, typy relacji łączy zapewniają afordancje wskazujące na zamiar. Każdy typ relacji ma określone znaczenie semantyczne. Dlatego czasami rozmawiamy o sieci semantycznej .

Aby zachować jak najjaśniejszy przykład, celowo ukryłem adresy URL w każdym linku. Gdy serwer hosting odbiera żądanie przychodzące, że ona wie, że fdaIXśrodki zamknięty , a CHTY91środki wyłączanie zasilania .

Zwykle po prostu kodowałbym akcję w samym adresie URL, aby adresy URL były /vms/1234/shut-downi /vms/1234/power-off, ale podczas uczenia, zaciera to rozróżnienie między typami relacji (semantyka) i adresami URL (szczegóły implementacji).

W zależności od posiadanych klientów możesz rozważyć, aby nie można hakować adresów URL RESTful .

CQRS

Jeśli chodzi o CQRS, jedną z niewielu rzeczy, o których zgadzają się Greg Young i Udi Dahan, jest to, że CQRS nie jest architekturą najwyższego poziomu . Dlatego byłbym ostrożny w tworzeniu interfejsu API RESTful zbyt podobnego do CQRS, ponieważ oznaczałoby to, że klienci staną się częścią Twojej architektury.

Często siłą napędową prawdziwego interfejsu API RESTful (poziom 3) jest chęć rozwijania interfejsu API bez rozbijania klientów i bez kontroli nad nimi. Jeśli to twoja motywacja, CQRS nie byłby moim pierwszym wyborem.

Mark Seemann
źródło
Czy masz na myśli, że oba pierwsze przykłady nie są ODPOWIEDNIE, ponieważ nie używają formantów hipermedialnych? Ale nawet nie opublikowałem żadnych odpowiedzi, tylko adresy URL żądań i treści.
leifbattermann
4
@leifbattermann Nie są RESTful, ponieważ używają treści wiadomości do komunikowania zamiarów; to wyraźnie RPC. Jeśli użyłeś linków, aby dotrzeć do tych zasobów, to dlaczego miałbyś komunikować zamiar poprzez ciało?
Mark Seemann,
To ma sens. Dlaczego sugerujesz POST? Czy akcja nie jest idempotentna? W każdym razie, jak powiedzieć klientowi, której metody HTTP użyć?
leifbattermann
2
@ guillaume31 DELETEwydaje mi się dziwny, ponieważ po wyłączeniu vm nadal będzie istniał, tylko w stanie „power off” (lub coś takiego).
leifbattermann
1
Zasób nie musi odzwierciedlać maszyny wirtualnej przed chwilą, może reprezentować jej instancję wykonania.
guillaume31,
6

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. PUTto 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-09b4e7abbf8bjest 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.

VoiceOfUnreason
źródło
2

Można użyć 5 poziomów typu nośnika, aby określić polecenie w polu nagłówka typu treści żądania.

W przykładzie maszyny wirtualnej byłoby to coś takiego

PUT /api/virtualmachines/42
Content-Type:application/json;domain-model=PowerOnVm

> HTTP/1.1 201 Created
Location: /api/virtualmachines/42/instance

Następnie

DELETE /api/virtualmachines/42/instance
Content-Type:application/json;domain-model=ShutDownVm

Lub

DELETE /api/virtualmachines/42/instance
Content-Type:application/json;domain-model=PowerOffVm

Zobacz https://www.infoq.com/articles/rest-api-on-cqrs

guillaume31
źródło
Informujemy, że 5LMT było proponowanym rozwiązaniem i nie jest obsługiwane przez standardy . Natknąłem się na CQRS artykułu przed i nauczyłem się wiele od niego.
Peter L
1

Przykład w połączonym artykule opiera się na pomyśle, że uruchomienie komputera i wyłączenie go musi być kierowane przez polecenia zamiast przez zmiany stanu modelowanych zasobów. To ostatnie jest właściwie tym, czym REST żyje i oddycha. Lepsze modelowanie maszyny Wirtualnej wymaga spojrzenia na to, jak działa jej odpowiednik w świecie rzeczywistym i jak Ty, jako człowiek, mógłbyś z nią współdziałać. Jest to długa droga, ale myślę, że daje dobry wgląd w rodzaj myślenia wymagany do dobrego modelowania.

Istnieją dwa sposoby kontrolowania stanu zasilania komputera na moim biurku:

  • Przełącznik zasilania: natychmiast odcina dopływ prądu do zasilacza, powodując nagłe, nieuporządkowane zatrzymanie całego komputera.
  • Włącznik / wyłącznik: Informuje sprzęt, aby powiadomił oprogramowanie, że coś na zewnątrz chce wszystko zamknąć. Oprogramowanie wykonuje uporządkowane zamykanie, powiadamia sprzęt, że jest zrobiony, a sprzęt sygnalizuje zasilaczowi, że może przejść do stanu gotowości. Jeśli włącznik zasilania jest włączony, urządzenie działa, a oprogramowanie znajduje się w stanie, w którym nie może reagować na sygnał wyłączenia, system nie zamknie się, dopóki nie wyłączę wyłącznika zasilania. (Maszyna wirtualna będzie zachowywać się dokładnie w ten sam sposób; jeśli oprogramowanie zignoruje sygnał zamknięcia, maszyna będzie kontynuować działanie, muszę ją wymusić wyłączenie.) Jeśli chcę móc ponownie uruchomić maszynę, muszę włącz ponownie włącznik zasilania, a następnie naciśnij przycisk włączania / wyłączania. (Wiele komputerów ma opcję długiego naciśnięcia przycisku zasilania, aby przejść bezpośrednio do stanu gotowości, ale ten model tak naprawdę tego nie potrzebuje.) Ten przycisk można traktować jak przełącznik, ponieważ jego naciśnięcie powoduje różne zachowanie w zależności od stanu po naciśnięciu. Jeśli wyłącznik zasilania jest wyłączony, naciśnięcie tego przycisku absolutnie nic nie robi.

W przypadku maszyny wirtualnej oba mogą być modelowane jako wartości logiczne do odczytu / zapisu:

  • power- Po zmianie na truenic się nie dzieje poza odnotowaniem, że przełącznik został ustawiony w tym stanie. Po zmianie falsena maszyna wirtualna otrzymuje polecenie natychmiastowego wyłączenia. Dla kompletności, jeśli wartość nie zmieni się po zapisie, nic się nie stanie.

  • onoff- Po zmianie na truenic się nie dzieje, jeśli powerjest false, w przeciwnym razie polecenie uruchomienia maszyny wirtualnej. Po zmianie na falsenic się nie dzieje, jeśli tak nie powerjest false, w przeciwnym razie maszyna wirtualna otrzyma polecenie powiadomienia oprogramowania o zaplanowanym wyłączeniu, co zrobi, a następnie powiadomi maszynę wirtualną, że może przejść w stan wyłączenia. Ponownie, dla kompletności, zapis bez zmian nic nie robi.

Z tym wszystkim wynika, że ​​istnieje jedna sytuacja, w której stan maszyny nie odzwierciedla stanu przełączników, i to podczas wyłączania. powernadal będzie truei onoffbędzie false, ale procesor nadal się wyłącza i do tego musimy dodać kolejny zasób, abyśmy mogli powiedzieć, co faktycznie robi maszyna:

  • running- Wartość tylko do odczytu, która występuje, truegdy maszyna wirtualna jest uruchomiona, a falsekiedy nie, określana przez zapytanie hiperwizora o jej stan.

Wynikiem tego jest to, że jeśli chcesz, aby maszyna wirtualna została uruchomiona, musisz upewnić się, że poweri onoffzasoby zostały ustawione true. (Możesz zezwolić na powerpominięcie tego kroku poprzez samodzielne zresetowanie go, tak aby po ustawieniu falsestał się truepo tym, jak maszyna wirtualna została mocno zatrzymana. Czy to RESTYSTYCZNIE czysta rzecz do zrobienia to pasza na kolejną dyskusję.) Jeśli chcesz to zrobić procedurę zamykania, można ustawić onoff, aby falsei wrócić później, aby sprawdzić, czy urządzenie rzeczywiście zatrzymał się, ustawiając powersię false, czy nie.

Podobnie jak w prawdziwym świecie, nadal masz problem z uruchomieniem maszyny wirtualnej po onoffzmianie, falseale nadal występuje, runningponieważ jest w trakcie zamykania. Sposób, w jaki sobie z tym radzisz, jest decyzją polityczną.

Blrfl
źródło
0

Czy oba projekty są RESTful?

Jeśli więc chcesz myśleć spokojnie, zapomnij o poleceniach. Klient nie mówi serwerowi, aby zamknął maszynę wirtualną. Klient „zamyka dow” (mówiąc metaforycznie) swoją kopię reprezentacji zasobu, aktualizując jej stan, a następnie umieszcza tę reprezentację z powrotem na serwerze. Serwer akceptuje tę nową reprezentację stanu i jako efekt uboczny faktycznie wyłącza maszynę wirtualną. Aspekt skutków ubocznych należy do serwera.

To mniej

Hej, serwerze, tutaj klient, czy mógłbyś wyłączyć maszynę wirtualną?

i więcej

Hej, serwer, klient tutaj, zaktualizowałem stan zasobu VM 42 do stanu zamknięcia, zaktualizowałem kopię tego zasobu, a następnie zrobiłem to, co uważasz za stosowne

Jako efekt uboczny serwera akceptującego ten nowy stan może on sprawdzić, jakie działania musi faktycznie wykonać (np. Fizycznie zamknąć VM 42), ale jest to przezroczyste dla klienta. Klient nie jest zainteresowany żadnymi działaniami, które serwer musi podjąć, aby zachować zgodność z tym nowym stanem

Więc zapomnij o poleceniach. Jedynymi poleceniami są czasowniki w HTTP dla transferu stanu. Klient nie wie ani nie dba o to, jak serwer doprowadzi fizyczną maszynę wirtualną do stanu zamknięcia. Klient nie wydaje serwerowi poleceń, aby to osiągnąć, po prostu mówi, że to jest nowy stan, zrozum to .

Siła tego polega na tym, że oddziela klienta od serwera pod względem kontroli przepływu. Jeśli później serwer zmieni sposób działania z maszynami wirtualnymi, klient nie będzie się tym przejmował. Brak punktów końcowych polecenia do zaktualizowania. W RPC, jeśli zmienisz punkt końcowy interfejsu API z shutdownna shut-down, zepsułeś wszystkich swoich klientów, ponieważ nie znają teraz polecenia do wywołania na serwerze.

REST jest podobny do programowania deklaratywnego, w którym zamiast wypisywania zestawu instrukcji, aby coś zmienić, wystarczy podać, jak chcesz, i pozwolić środowisku programistycznemu to określić.

Cormac Mulhall
źródło
Dziękuję za odpowiedź. Druga część dotycząca oddzielenia klienta od serwera bardzo dobrze pasuje do mojego własnego zrozumienia. Czy masz zasób / link, który tworzy kopię zapasową pierwszej części odpowiedzi? Dokładnie jakie ograniczenie REST jest przełamane, jeśli używam zasobów, metod HTTP, hipermediów, komunikatów samoopisujących itp.?
leifbattermann
Nie ma problemu z używaniem zasobów, metod HTTP itp. HTTP to mimo wszystko protokół RESTful. Tam, gdzie pojawia się problem, używa się tego, co nazywacie „punktami końcowymi akcji”. W REST istnieją zasoby, które reprezentują pojęcia lub rzeczy (takie jak maszyna wirtualna 42 lub moje konto bankowe), a czasowniki HTTP używają do przesyłania stanu tych zasobów między klientami i serwerami. To jest to. To, czego nie powinieneś robić, to próbować tworzyć nowe polecenia, łącząc punkty końcowe niebędące zasobami z czasownikami HTTP. Zatem 'virtualmachines / 42 / action' nie jest zasobem i nie powinien istnieć w systemie RESTful.
Cormac Mulhall
Innymi słowy, klient nie powinien próbować uruchamiać poleceń na serwerze (poza ograniczonymi czasownikami HTTP dotyczącymi wyłącznie przesyłania zasobów przez stan). Klient powinien aktualizować swoją kopię zasobu, a następnie po prostu poprosić serwer o zaakceptowanie tego nowego stanu. Zaakceptowanie tego nowego stanu może mieć skutki uboczne (VM 42 jest fizycznie zamknięty), ale to nie leży w gestii klienta. Jeśli klient nie próbuje uruchamiać poleceń na serwerze, nie ma sprzężenia za pomocą tych poleceń między klientem a serwerem.
Cormac Mulhall
Możesz uruchomić polecenie na zasobie ... Jak by to powiedzieć powiedz „wpłać” i „wypłać” na konto bankowe? Byłoby używać CRUD do czegoś, co nie jest CRUD.
Konrad
Lepiej używać POST /api/virtualmachines/42/shutdownzamiast mieć „efekt uboczny”. Interfejs API musi być zrozumiały dla użytkownika. Skąd mam wiedzieć, że na przykład DELETE /api/virtualmachines/42zamknie maszynę wirtualną? Efektem ubocznym jest dla mnie błąd. Powinniśmy zaprojektować nasze interfejsy API tak, aby były zrozumiałe i opisowe
Konrad