2009-05-24 12 views
21
new_story GET  /story/new(.:format) {:action=>"new", :controller=>"stories"} 
edit_story GET  /story/edit(.:format) {:action=>"edit", :controller=>"stories"} 
    story GET  /story(.:format)  {:action=>"show", :controller=>"stories"} 
      PUT  /story(.:format)  {:action=>"update", :controller=>"stories"} 
      DELETE /story(.:format)  {:action=>"destroy", :controller=>"stories"} 
      POST /story(.:format)  {:action=>"create", :controller=>"stories"} 

W pracy sieciowej, którą wykonałem z innymi technologiami, stosowałem tylko metody GET i POST. Ale przy RESTful trasach w Railsach, domyślnie metody PUT i DELETE są używane do aktualizacji i niszczenia akcji. Jaka jest przewaga lub potrzeba użycia PUT i DELETE? Zakładam, że te metody są po prostu innym sposobem wykonywania POST - ale dlaczego nie po prostu trzymać się POST?Dlaczego warto stosować metody HTTP PUT i DELETE zamiast POST?

Odpowiedz

45

Zaleta jest głównie semantyczna, a także może w pewnym stopniu uprościć adresy URL. Różne metody HTTP mapować do różnych działań:

POST => create a new object 
DELETE => delete an object 
PUT => modify an object 
GET => view an object 

Następnie w teorii, można użyć samo URL, ale z nim kontaktować za pomocą różnych metod; metoda używana do uzyskania dostępu do zasobu definiuje faktyczny typ operacji.

W praktyce jednak większość przeglądarek obsługuje tylko HTTP GET i POST. Railsy używają pewnych "sztuczek" w formularzach HTML, aby działały tak, jakby wysłano żądanie PUT lub DELETE, mimo że Rails wciąż używa GET lub POST dla tych metod. (To wyjaśnia, dlaczego nie używałeś DELETE lub PUT na innych platformach.)

+0

dobre wyjaśnienie. Nie wdając się w zbyt wiele szczegółów, o jakich "oszustach" mówimy? –

+11

To naprawdę proste. Podczas korzystania z metod Rails do generowania formularzy, jeśli podasz PUT lub DELETE, Railsy faktycznie POST formularz, ale zawiera ukryte pole w formularzu, który określa żądaną metodę HTTP. Następnie, podczas przetwarzania formularza, Railsy szukają tego ukrytego pola, a jeśli istnieje, zgłasza (poprzez obiekt żądania), że formularz został wysłany za pomocą DELETE lub PUT, mimo że został on rzeczywiście wysłany za pomocą POST. Zasadniczo, jeśli wybierzesz DELETE, request.method zwróci: delete, nawet jeśli formularz został POSTed. To wszystko dzieje się automagicznie. – mipadi

+0

To jest proste. Dzięki. –

6

To byłoby trochę jak pytanie "skasuj" plik, kiedy możesz ustawić jego zawartość na zero bajtów, a system plików potraktuj to jako usunięcie. HTTP na zawsze wspierał czasowniki inne niż GET/POST, ale sposób, w jaki SOAP ewoluował, nieco przekręcił pierwotne znaczenie tych czasowników. REST jest prostszym, z powrotem do podstawowym podejściem, które używa czasowników tak jak były przeznaczone zamiast wymyślać nową koncepcję czasownika wewnątrz ładunku.

8

Oto "methods" section of the HTTP 1.1 spec; definiuje wiele metod i wszystkie mają różne korzyści i kompromisy. POST jest najbardziej elastyczny, ale kompromisy są liczne: nie jest buforowalny (więc reszta Internetu nie może pomóc w skalowaniu), nie jest bezpieczna ani idempotentna, więc klient nie może po prostu ponownie wysłać błędu, i nie jest już jasne, co dokładnie chcesz osiągnąć (ponieważ jest tak elastyczny). Jestem pewien, że są inni, ale to powinno wystarczyć. Biorąc pod uwagę to wszystko, jeśli specyfikacja HTTP definiuje metodę, która spełnia dokładnie to, co chcesz, aby to zrobić, nie ma powodu, aby wysyłać zamiast tego POST.

Powodem, dla którego jest tak powszechny, jest to, że przynajmniej historycznie przeglądarki internetowe obsługują tylko GET i POST. Ponieważ GET jest zdefiniowany jako bezpieczny i idempotentny (nawet jeśli wiele aplikacji nie stosuje się do tego), jedynym sposobem modyfikacji danych był wysłanie POST. Wraz z rozwojem klientów AJAX i innych niż przeglądarka przestaje to być prawda.

BTW, mapowanie @mipadi podany jest standardowego mapowania, ale nie jest to jedyny prawidłowy. Na przykład Amazon S3 używa PUT do tworzenia zasobów. Jedynym powodem używania POST jest to, że klient nie ma wystarczającej wiedzy, aby utworzyć zasób, np., Gdy wykonujesz kopię zapasową zasobów za pomocą relacyjnej bazy danych i używasz sztucznych kluczy zastępczych.

+0

Dzięki. Nie wiedziałem o idempotent. Ciekawa funkcja. Nie mogę jednak pomyśleć, jak by to wykorzystać. –

+2

Spróbuj ponownie w przypadku niepowodzenia; jeśli nie dostaniesz "potwierdzenia", możesz po prostu wysłać to ponownie - gwarantowane jest, że nie różni się to od tego, czy pierwszy zadziałał. –

0

Chciałem tylko dodać coś do zaakceptowanej odpowiedzi, ponieważ jest to zbyt szeroka i bardzo stara odpowiedź.

mam zamiar podkreślić niektóre z najważniejszych bitów w RFC 2616 by W3

mam zamiar zacząć PUT ponieważ moim zdaniem ma największe zamieszanie otaczającego go.

  • PUT is used for both create/update PUT updates by completely replacing the resource on the server with the resource sent in the request

Na przykład

dokonać tego połączenia na moim api

PUT  /api/person 
{ 
    Name: John, 
    email: [email protected] 
} 

mój serwer ma tę część dzienną na serwerze

{ 
    Name: Jane, 
    email: [email protected] 
} 

Teraz mój istniejący zasób został całkowicie zastąpiony przez to, co wysłałeś i to jest to, co mam na moim serwerze.

{ 
    Name: John, 
    email: [email protected] 
} 

Więc jeśli PUT i tylko wysłać e-mail w organizmie

PUT  /api/person 
{ 
    email: [email protected] 
} 

mój serwer będzie całkowicie zastąpić jednostkę

{ 
    Name: Jane, 
    email: [email protected] 
} 

Z

{ 
    email: [email protected] 
} 

i nazwa będzie g jeden. Częściowe aktualizacje są dla PATCH, ale mimo to używam do tego POST.

  • One of the main reasons why we create/update with put is because it is idempotent.

To tylko wyobraźnia termin i podstawowa definicja to jest wielokrotne identyczne wnioski są takie same dla pojedynczego żądania.

Przykład

Przypuśćmy PUT plik do api/file jeśli serwer pochodzenie nie okaże się, że plik będzie utworzyć. Jeśli znajdzie plik, całkowicie zastąpi stary plik tym, który wysłałem. Zapewnia to, że jeden plik zostanie kiedykolwiek utworzony i zaktualizowany. Jeśli nie istnieje żaden plik i zadzwonię na numer PUT 5 razy, za pierwszym razem utworzy plik, a następnie 4 razy zastąpi plik tym, co wysyłasz. Jeśli zadzwonisz pod numer POST 5 razy, aby go utworzyć, utworzy 5 plików.

  • You PUT to that exact URI. If you don't you have to send a 301 (Moved Permanently) to the user and allow then make a choice whether or not to redirect the request. Most times the server you PUT to usually hosts the resource and takes care of updating it

To są główne punkty kiedy użyć PUT

miarę POST dotyczy

  • You can also create/update and then some...

Jak wspomniałem powyżej, istnieje kilka kluczowych różnic.

  • Post jest bardziej ogólny. W jaki sposób?niektóre inne przykłady zawierają bramę do innych protokołów, może ona przyjąć odpowiedź i wysłać ją do jakiejś obsługi danych w środku tam, lub może rozszerzyć jakąś funkcjonalność.
  • Wpis nie podlega ograniczeniu "Do dokładnego identyfikatora URI lub powiadomienia", na przykład POST może dołączyć zasób do istniejącej kolekcji i zdecydować, gdzie jest przechowywany.

A co z Delete Dlaczego nie po prostu POST?

Kiedy DELETE, serwer nie powinny odpowiedzieć sukces chyba usunąć zasób lub przenieść go do niedostępnej lokalizacji wówczas odpowiedź jest wysyłana.

Dlaczego to jest ważne? Co się stanie, jeśli zadzwonisz pod numer DELETE, ale zasób musi przejść "APPROVAL" przed usunięciem? Jeśli usunięcie może zostać odrzucone, nie można wysłać pomyślnie kodu błędu i jeśli postępujesz zgodnie z podstawową specyfikacją, jest to mylące dla osoby dzwoniącej. Tylko przykład Jestem pewien, że możesz wymyślić wiele innych.

Właśnie podkreślono niektóre z najważniejszych punktów na kiedy używać wspólnego Http verbs

Powiązane problemy