W drugim schemacie czasowniki są przechowywane w adresach URL zasobów. Należy tego unikać, ponieważ do tego celu należy używać czasowników HTTP. Zastosuj podstawowy protokół zamiast go ignorować, powielać lub zastępować.
Wystarczy spojrzeć DELETE /item/delete/:id
, umieszczasz te same informacje dwa razy w tym samym żądaniu. Jest to zbyteczne i należy tego unikać. Osobiście myliłbym się z tym. Czy interfejs API faktycznie obsługuje DELETE
żądania? Co się stanie, jeśli wstawię delete
adres URL i użyję innego czasownika HTTP? Czy to coś pasuje? Jeśli tak, który zostanie wybrany? Jako klient właściwie zaprojektowanego API nie powinienem zadawać takich pytań.
Być może potrzebujesz go w jakiś sposób do obsługi klientów, którzy nie mogą wydawać DELETE
ani PUT
żądać. W takim przypadku przekazałbym te informacje w nagłówku HTTP. Niektóre interfejsy API używają X-HTTP-Method-Override
nagłówka do tego konkretnego celu (co moim zdaniem i tak jest dość brzydkie). Z pewnością nie umieszczałbym czasowników na ścieżkach.
Idź po
GET /items # Read all items
GET /items/:id # Read one item
POST /items # Create a new item
PUT /items/:id # Update one item
DELETE /items/:id # Delete one item
Najważniejsze w czasownikach jest to, że są one już dobrze zdefiniowane w specyfikacji HTTP, a zgodność z tymi regułami pozwala na używanie pamięci podręcznej, serwerów proxy i ewentualnie innych narzędzi zewnętrznych w stosunku do aplikacji, które rozumieją semantykę HTTP, ale nie semantykę aplikacji . Należy pamiętać, że powodem, dla którego należy unikać umieszczania ich w adresach URL, nie jest to, że interfejsy API RESTful wymagają czytelnych adresów URL. Chodzi o unikanie niepotrzebnej dwuznaczności.
Co więcej, interfejs API RESTful może mapować te czasowniki (lub dowolny ich podzbiór) na dowolny zestaw semantyki aplikacji, o ile nie jest niezgodny ze specyfikacją HTTP. Na przykład jest całkowicie możliwe zbudowanie interfejsu API RESTful, który korzysta z żądań GET tylko wtedy, gdy wszystkie operacje na nim dozwolone są zarówno bezpieczne, jak i idempotentne . Powyższe mapowanie jest tylko przykładem, który pasuje do Twojego przypadku użycia i jest zgodny ze specyfikacją. Nie musi tak być.
Należy również pamiętać, że prawdziwie RESTful API nigdy nie powinien wymagać od programisty czytania obszernej dokumentacji dostępnych adresów URL, o ile przestrzega się zasady HATEOAS (Hypertext as Engine of Application State), która jest jednym z podstawowych założeń REST . Odsyłacze mogą być całkowicie niezrozumiałe dla ludzi, o ile aplikacja kliencka może je zrozumieć i wykorzystać do ustalenia możliwych przejść stanu aplikacji.
PUT
iDELETE
wolałbym dodać go do ścieżki, nie różnicując go ciągiem zapytania. To nie jest modyfikacja ciągu zapytania do istniejącej operacji; to osobna operacja.Pierwszy.
URI / URL to identyfikator zasobu (wskazówka w nazwie: jednolity identyfikator zasobu). Zgodnie z pierwszą konwencją zasób, o którym mówi się podczas wykonywania polecenia „GET / user / 123”, a zasób, o którym mówi się, gdy wykonuje się polecenie „DELETE / user / 123”, jest wyraźnie tym samym zasobem, ponieważ ma ten sam adres URL.
W przypadku drugiej konwencji nie można mieć pewności, że „GET / user / 123” i „DELETE / user / delete / 123” faktycznie są tym samym zasobem i wydaje się sugerować, że usuwa się powiązany zasób, a nie zasób sam w sobie, więc raczej zaskakujące jest to, że usunięcie
/user/delete/123
faktycznie usuwa/user/123
. Jeśli wszystkie operacje działają na różnych adresach URL, identyfikator URI nie działa już jako identyfikator zasobu.Kiedy mówisz
DELETE /user/123
, mówisz „usuń” rekord użytkownika o identyfikatorze 123 ”. Chociaż, jeśli powieszDELETE /user/delete/123
, to sugerujesz, że „usuwasz” rekord użytkownika usuwający z identyfikatorem 123 ”, co prawdopodobnie nie jest tym, co chcesz powiedzieć. I nawet jeśli użyjesz bardziej poprawnego czasownika w tej sytuacji: „POST / user / delete / 123”, który mówi „wykonaj operację dołączoną do„ deletora użytkownika o identyfikatorze 123 ””, nadal jest to okrężny sposób na usunięcie rekordu (jest to podobne do czasownika w języku angielskim).Jednym ze sposobów myślenia o adresie URL jest traktowanie go jak wskaźników do obiektów i zasobów jako obiektów w programowaniu obiektowym. Gdy to zrobisz
GET /user/123
,DELETE /user/123
możesz pomyśleć o nich myśleć jako metody w obiekcie:[/user/123].get()
,[/user/123].delete()
gdzie[]
jest jak wskaźnik operatora wyłuskania ale dla URL (jeśli znasz języka, które mają wskaźniki). Jedną z podstawowych zasad REST jest jednolity interfejs, tzn. Posiadanie małego i ograniczonego zestawu czasowników / metod, które działają na wszystko w rozległej sieci zasobów / obiektów.Dlatego pierwszy jest lepszy.
PS: oczywiście patrzy się na REST w najczystszy sposób. Czasami praktyczność przebija czystość i trzeba zrobić ustępstwa dla martwych mózgów klientów lub platformy, która utrudnia prawidłowe REST.
źródło
(przepraszam, mój pierwszy raz przegapiłem / edit / i / delete / in (2) ...)
Idea URI polega na tym, że jest to identyfikator zasobu adresowalnego , a nie wywołanie metody . Dlatego identyfikator URI powinien wskazywać określony zasób. A jeśli uszanujesz identyfikator URI, zawsze powinieneś uzyskać ten sam zasób.
Oznacza to, że powinieneś myśleć o identyfikatorach URI w taki sam sposób, jak myślisz o kluczu podstawowym wiersza w bazie danych. To jednoznacznie identyfikuje coś: Universal Resource Identifier.
Niezależnie od tego, czy używasz liczby mnogiej czy pojedynczej, identyfikator URI powinien być identyfikatorem, a nie wywołaniem . To, co próbujesz zrobić, odbywa się w metodzie, a mianowicie: GET (pobierz), PUT (utwórz / zaktualizuj), DELETE (usuń) lub POST (wszystko inne).
Zatem „/ item / delete / 123” przerywa REST, ponieważ nie wskazuje zasobu, jest raczej wywołaniem metody.
(Również semantycznie powinieneś być w stanie UZYSKAĆ URI, zdecydować, że jest nieaktualny, a następnie USUNĄĆ ten sam URI - ponieważ jest to identyfikator. Jeśli GET URI nie ma „/ delete /”, a DELETE ma, to jest sprzeczne z semantyką HTTP. Nadajesz 2 lub więcej identyfikatorów URI na zasób, gdzie 1 to zrobi.)
Teraz oszustwo jest takie: nie ma naprawdę jasnej definicji tego, co jest zasobem, a nie zasobem, więc powszechnym unikaniem w REST jest zdefiniowanie „rzeczownika przetwarzającego” i wskazanie na to URI. To właściwie gra słowna, ale spełnia semantykę.
Jeśli na przykład z jakiegoś powodu naprawdę nie można tego użyć:
możesz zadeklarować światu, że masz zasób przetwarzający „deletor” i jego użycie
Teraz wygląda to bardzo podobnie do RPC (Remote Procedura Call), ale przechodzi przez rozległą lukę w klauzuli „przetwarzania danych” specyfikacji POST nazwanej w specyfikacji HTTP.
Jednak robi to rodzaj wyjątkowe, a jeśli mogą korzystać ze wspólnej PUT dla tworzenia / UPDATE, DELETE do usunięcia, a POST dla append, tworzyć i wszystko inne, to powinien , bo to bardziej standardowe użycie protokołu HTTP. Ale jeśli masz trudny przypadek, taki jak „zatwierdzenie” lub „opublikuj” lub „zredaguj”, to przypadek użycia rzeczownika procesora spełnia wymagania purystów REST i nadal zapewnia semantykę, której potrzebujesz.
źródło