REST i ścieżki

Hej,

Może trochę się czepiam… :wink:
Mamy resources :foos w routes.rb, a w kontrolerze:

def create @foo = Foo.new(params[:foo]) if @foo.save flash[:info] = 'Foo created' redirect_to @foo else render :action => :new end end

Teraz jeśli tworzymy nowe foo (żądanie POST do /foos) i nie przechodzi walidacja, URL pozostaje /foos, ale renderujemy widok ‘new’ - który normalnie powinien być widoczny pod /foos/new. Analogicznie z edit/update.

A gdyby routing wyglądał tak:

foos GET /foos(.:format) {:controller=>"foos", :action=>"index"} GET /foos/:id(.:format) {:controller=>"foos", :action=>"show"} new_foo GET /foos/new(.:format) {:controller=>"foos", :action=>"new"} POST /foos/new(.:format) {:controller=>"foos", :action=>"create"} # ! edit_foo GET /foos/:id/edit(.:format) {:controller=>"foos", :action=>"edit"} PUT /foos/:id/edit(.:format) {:controller=>"foos", :action=>"update"} # ! foo DELETE /foos/:id(.:format) {:controller=>"foos", :action=>"destroy"}
nie byłoby spójniej, ładniej, fajniej i w ogóle? :slight_smile:

ja tak czasami robie, tylko w kontolerze wtedy trzeba if request.put? itp

Czy ładniej to kwestia gustu. :slight_smile: Na pewno nie byłoby to już RESTful (tabelka w “RESTful web services”). Dzięki REST można prosto dobrać się do web servisu - jest to zwykłe zapytanie HTTP. Powstaje warstwa abstrakcji, dzięki której łatwo po stronie klienta użyć dowolnego innego języka programowania.

Z drugiej strony barykady mamy SOAP i tony XML. :rolleyes:

REST nie specyfikuje schematu adresu, jedynie operacje na kolekcji lub zasobie, więc z tego co widzę zmiany proponowane astarotha były by jak najbardziej poprawne.

@hekto5: Gratuluję umiejętności napisania 5 zdań zupełnego bełkotu, w których albo nie masz racji ani nie odnosisz się do tematu .

Pomimo zabawnych pomówień o bełkot pozostanę przy zdaniu, że nie jest to poprawne w rozumieniu REST. :slight_smile:

REST mówi, że każdy zasób, czy kolekcja są identyfikowane przez konkretne URI, np dla kolekcji foos można użyć /foos lub /bar/foos lub /what/ever/foos lub /bar lub dowolnego innego URI. Czasownik POST oznacza ‘dodaj nowy element do kolekcji określonego przez URI’.

Co w takim razie u astaroth stanie się po wykonaniu POST /foos/new? Patrząc RESTowo na to zapytanie można spodziewać się, że zostanie dodany nowy element do kolekcji znajdującej się pod /foos/new. Niestety tak nie jest, nowy element zostanie dodany do kolekcji /foos. Jest to inna kolekcja niż określona przez URI w zapytaniu POST, co przeczy idei REST.

Więc skąd są te /foos/new i /foos/123/edit? Nie ma tego w REST. Idealnie byłoby móc używać dowolnych czasowników, jednak protokół HTTP tego nie dopuszcza. W RoR dodano więc możliwość definiowana dodatkowych akcji na zasobie. /new i /edit są takimi domyślnymi dodatkowymi akcjami upraszczającymi budowę aplikacji gdy formatem danych rozumianym przez klienta jest HTML. Klient rozumiejący np JSON nie korzysta z nich zupełnie.

Wojtek ma jak najbardziej rację. Wymyślanie koła nie ma sensu, ktoś mądrzejszy od Was to już wymyślił ;).

Zdaję sobie sprawę, że zmiana standardu jest raczej nierealna… Chciałem tylko filozoficznie zagaić na temat potencjalnych jego niedoskonałości :wink: Bardziej w stylu “czy gdybyśmy projektowali teraz REST od zera, zrobilibyśmy go tak samo?”

A wyjaśnienie podane przez hekto5 jest całkiem logiczne - w idealnym świecie REST mamy tylko URL-e kolekcji i obiektów, co jest wystarczające do manipulowania nimi. Czasami tylko aplikacja udostępnia specjalne ścieżki (/new, /id/edit), żeby wyświetlić użytkownikowi wygodny formularz, tudzież udostępnić inne informacje i funkcjonalności.

Jeszcze mi przyszło w międzyczasie do głowy, żeby zamiast render :action => :new wykonać redirect_to new_foo_path, ale wtedy tracimy parametry, flasha, itd., więc chyba już sobie daruję te dywagacje :slight_smile:

Cóż, po pierwsze należy odróżnić URL od URI przeglądarki używają pierwszego nie drugiego. Więc ten sam zasób jest jak najbardziej poprawnie identyfikowany przez wiele ścierzek.
Co więcej HTTP pozwala na wiele “czasowników” co więcej może być rozszerzany - patrz WebDAV - To przeglądarki nie mają odpowiednio zaimplementowanej obsługi ze względu na to ze standard W3C tego nie przewidział.
/edit /new itd. nie ma w specyfikacji REST bo nie są dla niej istotne, są poza zakresem i definiowane przez implementację - tu ukłon w stronę astarotha - twoja implementacja REST jest jak najbardziej poprawna. A żeby było jeszcze ciekawiej schemat “restowych” urli zmieniał się w rails od wersji . dokładnie razy, czyli co mądrzy ludzie wymyślili, potem przyszli mądrzejsi, poprawili, potem jeszcze mądrzejsi i znowu poprawili. Ale ja mam siedzieć cicho bo jestem leszcz i na pewno nie mądrzejszy niż ci inni hipotetyczni mądrzy ludzie?

Tak więc Wojtek gada bez składu i ładu, nie mając o niczym prawdziwego pojęcia a o standardach webowych to już najmniej. a Hubert modli się do wielkich przodków informatyków którzy są przecie nieomylni, i zawsze sprytniejsi od nas zwykłych zjadaczy chleba.

No, z tą poprawnością u astarotha to jedno nie pasuje: jeśli tworzenie nowego obiektu miało by się odbywać przez request idący na /foos/new to metodą powinno byc PUT a nie POST.

Ale generalnie mi jakoś nie wydaje się to ładniejsze (znaczy - używanie POSTów i PUTów na /new i /edit).

GET /foo/edit zwraca nie resource /foo tylko obiekt, który pomaga w edycji. Obiektem tym jest formatka HTML. Resource /foo/edit.xml może już nie mieć sensu (chyba żeby zwracało też coś w stylu szablonu XML, który się później wypełni wartościami).

Poczytaj o Uniform Resource Identifiers (URI). Zbiór wszystkich URL to podzbiór wszystkich URI. Wybacz jeśli miałeś problem ze zrozumieniem mojego posta z tego powodu, że pominąłem protokół i hosta pisząc ‘/foos’ itp.

“standard W3C” - rozumiem, że odnosisz się do HTML, tymczasem REST został wprowadzony do RoR, aby prawie automatycznie cała aplikacja stała się web serwisem. Z web serwisów korzystają głównie inne aplikacje, więc HTML i jego ograniczenia nie mają tu nic do rzeczy. Standard Hypertext Transfer Protocol – HTTP/1.1 opisuje 7 czasowników. Dodatkowo używa się też paru innych, np. CONNECT, PATCH (http://tools.ietf.org/html/rfc5789).

Na tym polega ewolucja. Za to cenię RoR, że ciągle rozwija się, zmienia, nie stoi w miejscu i dąży do pewnego ideału.

Ad a) chodziło mi o to że jeden zasób w brew pozorom może być identyfikowany przez wiele URI, więc nie ma problemu z dodaniem /edit na końcu, bo to nadal jest ten sam zasób.
Ad b) dokładnie o to mi chodziło, i chyba nie zauważyłeś, ale próbując udowodnić mi pomyłkę, sam przeczysz, bo najpierw twierdzisz że http nie dopuszcza dowolnych czasowników:

, po czym cytujesz standard protokołu który w punkcie 9tym wyraźnie twierdzi że zakres metod może być rozszerzony, co jest zgodne z moim postem.
Ad c) Tak, z tym że oznacza to że nie ma jednego “standardowego” zestawu REST-owych adresów, i propozycja astarotha powinna zostać rozważona pod względem merytorycznym, zamiast tego zjechałeś biedaka że próbuje drugiego SOAPa wymyślić - co jest oczywistą nie prawdą, po czym Hubert próbował go uciszyć czyimś autorytetem, co już jest zupełnym idiotyzmem.

Ależ w czym problem, Świstak? Pomysł w oryginalnym poście jest po prostu głupi, tego chyba nie zaprzeczysz?

Ależ nie przedstawiono dotychczas ŻADNYCH merytorycznych powodów dla których miałby być głupi. Na pewno ty tego nie zrobiłeś, z argumentacją hekto5tki się nie zgadzam głównie dlatego że ma błędy merytoryczne i dziury w argumentacji jak stąd do Warszawy. Tak więc zaprzeczam.
Teraz jeżeli sformułować pytanie, “czy jest sens teraz zmieniać obsługę REST w rails tak jak ja tego chcę?” odpowiadam oczywiście - NIE! i tutaj się zgadzamy, ale to nie takie pytanie zadał autor wątku!

PS.
Prowadzenie dyskusji i merytoryczne rozważanie za i przeciw jest raczej ideą działu “dyskusje”, argument “lepsi i mądrzejsi od ciebie to zrobili” nie jest w żadnym przypadku argumentem merytorycznym, nie jestem nawet pewien czy można go nazwać argumentem. Twierdzenie że coś nie jest REST i kropka dlatego jest be, jest argumentem, ale zwykle wymaga poparcia, zwłaszcza jeżeli ktoś uprzejmie zwraca uwagę że argument jest błędny, Można rozpocząć dyskusję, przytaczać argumenty i odnośniki i chyba po to jest to forum. Przy okazji autorytarne stwierdzenie że oś jest głupie bez żadnego uzasadnienia również nie uznaje za argument w dyskusji.

Ach, zapach flejma. Brakuje mi regularnego forumowania tutaj na wywczasie poza krajem :slight_smile: