Czy sesje po stronie serwera naruszają REST?

14

Zgodnie z Royem Fieldingiem (jednym z głównych autorów specyfikacji HTTP) w swojej pracy dyplomowej Style architektoniczne podczas omawiania REST , wspomina:

[E] Żądanie od klienta do serwera musi zawierać wszystkie informacje niezbędne do zrozumienia żądania i nie może korzystać z żadnego kontekstu przechowywanego na serwerze.

Przez „zapisany kontekst” odnosi się do stanu aplikacji, np. Jaki jest numer strony dla następnej strony, w porównaniu do stanu zasobów, np. Dowolnego magazynu danych, obrazu itp. - co jest prawdopodobnie całym celem REST.

Czy można uczciwie powiedzieć, że większość prób czystego odpoczynku (definiowanych niniejszym jako implementacja zgodna z powyższą tezą) musi zakończyć się niepowodzeniem z powodu polegania na przechowywaniu danych sesji na serwerze (trwałym lub innym)?

Pojęcie sesji jest wspólne - w szczególności dla programistów stron internetowych - ale czy jest zgodne z powyższą definicją?

Matt
źródło
2
Powiedziałbym, że zgodnie z tą definicją praktycznie nic nie jest uspokajające, ale jak ta definicja jest w ogóle logicznie uzasadniona? Wyobraź sobie „spokojną” wyszukiwarkę google, w której musisz podać indeks internetu w żądaniu, by wyszukiwarka go szukała. Co? Nie, powiedzenie, że nie możesz mieć sklepu z uporczywością i być spokojnym, byłoby równoznaczne z powiedzeniem, że spokojne interfejsy są w rzeczywistości bezcelowe. To nie znaczy, że wszyscy powinniśmy rozpocząć utrzymanie sesji w pamięci i mówiąc to wciąż dobry projekt reszta ...
Jimmy Hoffa
3
Myślę, że należy zauważyć, że istnieje różnica między stanem aplikacji a stanem zasobów (indeks Google byłby stanem zasobów i jest całkowicie uzasadniony). Powinienem to wyjaśnić w pytaniu.
Matt
jest takie rozróżnienie? Proszę to zdefiniować. :) Widziałem, jak ludzie próbują to zdefiniować wcześniej, ale robi się to naprawdę rozmyte, ponieważ tak naprawdę nie są różne. Oba są danymi zmiennymi, jedynym istotnym rozróżnieniem między jedną formą stanu a drugą jest to, czy jest ona trwała, czy nie, gdzie nie forma oznacza, że ​​zwykle można ją odtworzyć, co ją wyróżnia.
Jimmy Hoffa
1
Zastanawiałem się nad tym sam. Ponieważ nikt nigdy nie wyjaśnił, dlaczego moja aplikacja powinna chcieć złotej „spokojnej” gwiazdy, tak naprawdę nie martwię się o to.
psr

Odpowiedzi:

10

Powiedziałbym, że tak, stan sesji powoduje, że aplikacja RESTful nie jest RESTful. Trywialny przykład, moja siostra subskrybuje Wall Street Journal. Regularnie będzie czytać coś za zapłatą i zdecydować o wysłaniu linku (za pośrednictwem własnego klienta e-mail, a nie przez WSJ) do znajomego, który nie ma konta WSJ. Kliknij, wyślij, nie powiodło się. Oczywiście doświadczenie mojej siostry pod tym adresem URL różni się od doświadczenia jej przyjaciółki.

Powiązane, ale nie wyłącznie na temat: Jestem we wczesnej fazie projektowania aplikacji zaprojektowanej w celu wspierania znacznych wysiłków badawczych w sieci (zwanych zadaniami (pomyśl: zakładki na sterydach i LSD)). Właściciel zadania chce udostępnić konkretny widok swoich danych komuś innemu, ale ten widok wymaga kombinacji stanu interfejsu użytkownika (np. Które wizualizacje danych pokazują, w których oknach) oraz odpowiednich uprawnień dostępu do interfejsu użytkownika i wyświetlane dane. Odbiorca musi uzyskać dużo stanu zapisanego, aby uzyskać zamierzony widok.

Moje obecne rozwiązanie polega na przechowywaniu wszystkich informacji o interfejsie użytkownika / ACL / dowolnych informacjach niezbędnych do widoku w osobnym obiekcie i zwrócenie adresu URL (prawdopodobnie UUID) dla tego obiektu. Uważam, że dostęp do obiektu widoku można uznać za RESTful w tym sensie, że każdy, kto go posiada, otrzymuje te same informacje / doświadczenia.

Peter Rowell
źródło
1
Widzisz, przykład obiektu jest pod innym kątem. Schludny.
Matt
Zaakceptowanie tego jako odpowiedzi, pomimo innych świetnych odpowiedzi, głównie dlatego, że odpowiada bezpośrednio na pytanie i daje bardzo jasny przykład. Również druga część na obiektach widoku przechyliła skale.
Matt.
1
Jeśli mówisz, że witryna WSJ jest przykładem aplikacji, która nie spoczywa w spokoju, nie zgadzam się, że twój przykład to pokazuje. Jeśli na przykład witryna WSJ opiera się na danych podanych całkowicie przez klienta siostry w celu przedstawienia jej danych, to zgodnie z definicją podaną przez @Matt RESTful. Jeśli jednak opiera się na tymczasowym stanie sesji w pamięci, to według definicji Matt nie dał RESTful. Zwracam na to uwagę, ponieważ definicja podana przez Matta opiera się na szczegółach implementacji, podczas gdy REST jest lepiej definiowany przez technikę konsumpcji.
Jimmy Hoffa
@JimmyHoffa - Moje rozumienie ograniczeń REST polega na tym, że jest ono bezstanowe . Wydaje mi się to dość jednoznaczne.
Peter Rowell,
Jeśli aplikacja WSJ nie miałaby stanu, widoczny artykuł musiałby zostać przesłany przez klienta. Ten artykuł może być edytowany w dowolnym momencie przez administratorów strony, nie pomylcie się, to część stanu aplikacji WSJ. Myślę, że dąży się do rozróżnienia tego, że jest to stan trwały , więc będzie miał więcej gwarancji i mniej kosztów zarządzania niż stan trudny, taki jak sesje, a także prostsza kontrola atomowości w transakcjach na nim. To wraz z prostym modelem konsumpcji jest tym, na co ludzie chcą odpocząć. (Myślę)
Jimmy Hoffa
2

Czy sesje po stronie serwera naruszają REST?

Zdecydowanie tak! Po wdrożeniu REST nie może być sesji po stronie serwera, w przeciwnym razie masz hybrydowe rozwiązanie RPC / REST.

Klient musi wysłać do usługi RESTful cały kontekst niezbędny do obsługi żądania, w tym informacje niezbędne do uwierzytelnienia klienta, za każdym razem, gdy jest wysyłane nowe żądanie. Serwer może buforować informacje, aby przyspieszyć obsługę kolejnych żądań, ale buforowane informacje nie mogą oznaczać sesji po stronie serwera. Innymi słowy, samo żądanie musi zawierać wystarczającą ilość informacji do przetworzenia nawet przy braku stanu buforowanego.

dasblinkenlight
źródło
1

Prawdopodobnie zależy od tego, co rozumiesz przez „dane sesji”. Czy to dokładny termin?

Bezpieczna komunikacja między dwiema stronami często wymaga od serwera wygenerowania (i przechowywania) ograniczonego czasowo „tokena dostępu”, który klient musi dostarczyć przy każdym żądaniu jako sposób autoryzacji. Ten token dostępu jest już tym, co nazwałbym „danymi sesji” - jest przechowywany po stronie serwera, ograniczony czasowo i powiązany z jednym klientem (zwykle jego uprawnieniami).

Byłbym bardzo zaskoczony, gdyby tego rodzaju operacja została oznaczona jako nie-RESTful. OAuth jest przykładem.

Nie jestem specjalistą i nie jestem zbyt pewny siebie; Po prostu dzielę się swoimi spostrzeżeniami, mając nadzieję, że okażą się pomocne.

Kos
źródło
1

Najważniejszym punktem usługi REST jest to, że identyfikator URI dla zasobu zawsze wskazuje na ten sam zasób. Użytkownicy mogą więc przekazywać odniesienia do tego zasobu i każdy widzi to samo. Nazywa się to REST (Representational State Transfer). Jeśli serwer zachowuje stan i dostarcza inne zasoby dla tego samego identyfikatora URI, powiedziałbym, że nie jest to już czysty REST.

Puckl
źródło
niekoniecznie musi to być prawda, że ​​użytkownicy zobaczą to samo. Dostęp może decydować o tym, ile może zobaczyć każdy użytkownik.
Erik
@Erik Ale użytkownik powiedziałby, ile chce zobaczyć w żądaniu (w tym za pomocą nagłówka Accept Header), więc odpowiedzi Puckl są prawdziwe.
Johan
1
@Johan Zwrócę różne dane dla różnych użytkowników z tego samego punktu końcowego. W przeciwnym razie jaki jest sens uwierzytelnienia użytkownika.
Erik
@Erik Też bym to zrobił. Niemniej jednak uważam, że uwierzytelnianie wykracza poza stan zasobu, więc ściśle mówiąc, jeśli na widok ma wpływ uwierzytelniony użytkownik, nie jest już RESTful. Może jeśli chcesz mieć odznakę RESTful, powinieneś utworzyć wiele „widoków” zasobu, w zależności od tego, kto żąda dostępu, autoryzuje dostęp tylko do niektórych widoków. Tak więc publiczny może uzyskać dostęp do / userprofiles / {userID} / publicview, a użytkownik ma dostęp do / userprofiles / {userID} / fullprofile, a autoryzowani przyjaciele mogą uzyskać dostęp do / userprofiles / {userID} / friendsview
Johan
0

Sesje są zasadniczo używane do dodawania stanu do bezstanowych aplikacji RESTful. Formalnie sprawia to, że twoja aplikacja RESTful jest stanowa, jednak utrzymanie stanu serwera sprawia, że ​​twoje życie jest trochę łatwiejsze, ponieważ nie musisz przekazywać wszystkich danych tam iz powrotem przy każdym żądaniu / odpowiedzi.

Sesje, a bardziej ogólnie stan, pozwalają tego uniknąć, a to ma pewne pozytywne zalety pod względem wydajności (mniej przesyłanych danych) i bezpieczeństwa (mniej danych dostępnych do manipulowania).

Więc chociaż oficjalnie narusza część definicji REST, jest tak przydatna, że ​​rzadko można zobaczyć aplikacje RESTful, które nie używają stanu przez sesje.

Oleksi
źródło
Nie zgadzam się. Masz witrynę zakupów, która pozwala filtrować według marki, koloru i rozmiaru. Tradycyjne strony WWW 1.0 poradziłyby sobie z tym za pomocą niektórych pól wyboru, sesji po stronie serwera i testu POST. Jeśli chcę udostępnić link do example.org/shirts, ludzie nie zobaczą, że wybrałem Medium, Black i Roots. (Powoduje to również brzydki komunikat „ponownie PONOWUJ ​​dane” po kliknięciu). Ale jeśli udostępniam link do (np.) Example.org/shirts/medium-black-roots, wszyscy mają taką samą reprezentację. Wszystkie niezbędne informacje o stanie znajdują się w adresie URL (lub w treści POST, jeśli jest to konieczne, ale nie można tego udostępnić).
Jesse Buchanan
... RESTful może nie nadawać się do wszystkiego. Czy Twoja hipotetyczna aplikacja jest zorientowana na zasoby (z pewnością jest to strona zakupów!)? Być może nie nadaje się do RIA z dużą ilością stanów, które nie są zorientowane na zasoby. Szczerze mówiąc, nie mogę wymyślić żadnych dobrych przykładów.
Jesse Buchanan,
0

Przez Fielding rozumiane przez tę instrukcję jest to, że serwer aplikacji obsługujący interfejs API REST nie kojarzy stanu otoczenia z żądaniem jakiegoś mechanizmu ukrytego. Rozważ różnicę między serwerem aplikacji a serwerem bazy danych . Ograniczeniem REST jest to, że serwer aplikacji powinien być bezstanowy . Serwer aplikacji może jednak delegować żądania stanu zasobów do serwera bazy danych na podstawie informacji, które są częścią żądania, takich jak kombinacja użytkownik / hasło w nagłówku autoryzacji lub sam Uri. W końcu REST opiera się na modelu klient / serwer.

eulerfx
źródło