Mamy adres URL w następującym formacie
/ instance / {instanceType} / {instanceId}
Możesz to nazwać standardowymi metodami HTTP: POST, GET, DELETE, PUT. Jest jednak kilka innych działań, które podejmujemy, takich jak „Zapisz jako wersję roboczą” lub „Wybawiciel”
Pomyśleliśmy, że możemy po prostu użyć niestandardowych metod HTTP, takich jak: DRAFT, VALIDATE, CURATE
Myślę, że jest to dopuszczalne, ponieważ normy mówią
„Zestaw typowych metod dla HTTP / 1.1 jest zdefiniowany poniżej. Chociaż można go rozszerzyć, nie można założyć, że dodatkowe metody współużytkują tę samą semantykę dla osobno rozszerzonych klientów i serwerów”.
Narzędzia takie jak WebDav tworzą własne rozszerzenia.
Czy są problemy, na które natrafił ktoś przy użyciu niestandardowych metod? Mam na myśli serwery proxy i zapory ogniowe, ale wszelkie inne obszary zainteresowań są mile widziane. Czy powinienem pozostać po bezpiecznej stronie i mieć tylko parametr adresu URL, taki jak action = validate | curate | draft?
Odpowiedzi:
Jednym z podstawowych ograniczeń HTTP oraz z centralnym elementem projektowania reszta to jednolity interfejs dostarczone przez (między innymi) niewielki, stały zestaw metod, które stosuje się powszechnie do wszystkich zasobów. Ujednolicone ograniczenie interfejsu ma wiele zalet i wad. Cytuję z Fielding liberalnie tutaj.
Jednolity interfejs:
Z drugiej strony jednolity interfejs:
Kompromisy są „zaprojektowane dla powszechnego przypadku sieci” i pozwoliły zbudować duży ekosystem, który zapewnia rozwiązania wielu typowych problemów w architekturze sieci. Przestrzeganie jednolitego interfejsu pozwoli systemowi czerpać korzyści z tego ekosystemu, a jego złamanie utrudni to. Możesz użyć modułu równoważenia obciążenia, takiego jak nginx, ale teraz możesz używać tylko modułu równoważenia obciążenia, który rozumie DRAFT i CURATE. Możesz chcieć użyć warstwy pamięci podręcznej HTTP, takiej jak Varnish, ale teraz możesz używać tylko warstwy pamięci podręcznej HTTP, która obsługuje DRAFT i CURATE. Możesz poprosić kogoś o pomoc w rozwiązywaniu problemów z awarią serwera, ale nikt inny nie zna semantyki żądania CURATE. Zmiana preferowanych bibliotek klienta lub bibliotek serwera może być trudna do zrozumienia i prawidłowego wdrożenia nowych metod. I tak dalej.
Prawidłowym * sposobem na przedstawienie tego jest transformacja stanu zasobu (lub zasobów pokrewnych). Nie tworzysz posta, transformujesz jego
draft
stantrue
lub tworzyszdraft
zasób, który zawiera zmiany i linki do poprzednich wersji roboczych. Nie LECZESZ posta, transformujesz jegocurated
stantrue
lub tworzyszcuration
zasób, który łączy post z użytkownikiem, który go wyleczył.* Prawidłowe, ponieważ najściślej przestrzega zasad architektury REST.
źródło
Wolałbym zaprojektować je jako pod-zasoby, na które wykonujesz żądanie POST.
Biorąc pod uwagę, że masz zasób
/instance/type/1
, chciałbym, aby reprezentacja tego zasobu zawierała kilka linków do „działań”, które można wykonać na zasobie, takich jak/instance/type/1/draft
i/instance/type/1/curate
. W JSON może to być tak proste, jak:Dzięki temu klient może bardzo wyraźnie powiedzieć, co musi się zdarzyć, podczas żądania POST do linku podanego przez
curate
członka. Umieszczony tam zasób może zawierać argumenty opisujące zdarzenie, które być może spowodują zmianę stanu.Stosowanie „naiwnego” podejścia polegającego na przechodzeniu między możliwymi stanami zasobu ma tę wadę, że nie rejestruje zdarzeń, które doprowadziły do tych przejść.
Przejścia stanu zwykle następują w odpowiedzi na określone zdarzenia i wolę uchwycić te zdarzenia, niż pozwolić klientowi zdecydować, że coś jest teraz w określonym „stanie”. Utrudnia to również walidację. Ponadto nie będziesz w stanie uchwycić żadnych „argumentów”, chyba że opisujesz również te w samym stanie. A potem robi się niedobrze, gdy jakiś kod zmienia te bez rzeczywistego przejścia stanu i wymagana jest weryfikacja, a wszystko szybko staje się bałaganem.
źródło
/vms/some-id
zwraca linki do akcji takich jakPOST /vms/some-id/restart
i używamy go do ustalenia, czy akcje powinny być włączone czy wyłączone. Mam związek miłości / nienawiści z HATEOAS :)Myślę, że niestandardowa metoda HTTP jest najlepszym sposobem na wdrożenie działań encji. Dodanie akcji do ciała encji (POST) wydaje się niewłaściwe, nie jest częścią twojej encji (chociaż wynik może zostać w niej zapisany). Ponadto za pomocą niestandardowych metod HTTP serwery proxy mogą określać ich działania bez konieczności analizowania treści encji.
To jest jak CRUD, zawsze chciałbyś je wdrożyć, ale masz też swój własny zestaw akcji (na enitity). Naprawdę nie rozumiem, jaki byłby problem z ich przedłużeniem.
Również @Rein Henrichs „Nie tworzysz posta, zmieniasz jego stan szkicu na prawdziwy lub tworzysz zasób szkicu” wydaje mi się fałszywy.
drafts
Nieruchomość będą wykorzystywane do zapisywania trwały stan, a nie do dokonywania transformacji. Działania niekoniecznie prowadzą do „stanu” lub nie są zapisywane we właściwości. Tworzenie osobnego bytu dla każdego stanu / transformacji wydaje się jeszcze bardziej rozmyte. Spróbuj zachować to samo odwołanie (URI) do enity.źródło