rest教學 - web service restful




如果REST應用程序應該是無狀態的,那麼您如何管理會話? (8)

我需要一些澄清。 我一直在閱讀REST,並構建RESTful應用程序。 根據維基百科,REST本身被定義為具象狀態傳輸 。 因此,我不明白所有這些每個人都在不停地噴湧的無國籍的gobbledeygook

從維基百科:

在任何特定時間,客戶可以在應用程序狀態之間轉換或“靜止”。 處於休眠狀態的客戶端能夠與其用戶進行交互,但不會創建任何負載,也不會在該組服務器或網絡上佔用每個客戶端的存儲空間。

他們只是說不使用會話/應用程序級別的數據存儲?

例如,我知道REST的一個目標是使URI訪問一致並可用,而不是在帖子內部隱藏分頁請求,使得請求的頁碼成為GET URI的一部分。 我感覺合理。 但它似乎只是過度的說, 每個客戶端數據 (會話數據)都不應該存儲在服務器端。

如果我有一個消息隊列,並且我的用戶想要閱讀這些消息,但是在他閱讀這些消息時,想要阻止某些發送者在會話期間發送的消息? 將它存儲在服務器端的地方並讓服務器只發送未被用戶阻止的消息(或消息ID)是否有意義?

每次我請求新的消息列表時,是否真的必鬚髮送整個消息發送者列表來阻塞? 與我相關的消息列表首先不會/不應該是公開可用的資源。

再次,只是試圖理解這一點。 有人澄清。

更新:

我發現了一個堆棧溢出的問題,它的答案並不完全讓我一直在那裡: 如何管理REST中的狀態,它說明重要的客戶端狀態應該全部在每個請求上傳輸.... Ugg ..似乎有很多開銷......這是對的嗎?


他們只是說不使用會話/應用程序級別的數據存儲?

不,他們並不是以微不足道的方式說這些話的。

他們說不定義“會話”。 不要登錄。 不要註銷。 為請求提供憑據。 每個請求都是獨立的。

你還有數據存儲。 您仍然擁有身份驗證和授權。 您不必浪費時間建立會話並保持會話狀態。

問題在於每個請求(a)完全獨立,(b)可以在沒有任何實際工作的情況下輕鬆實現到一個巨大的並行服務器場。 Apache或Squid可以盲目且成功地傳遞RESTful請求。

如果我有一個消息隊列,並且我的用戶想要閱讀這些消息,但是在他閱讀這些消息時,想要阻止某些發送者消息在會話期間通過?

如果用戶需要過濾器,那麼只需在每個請求上提供過濾器即可。

對於服務器只發送未被用戶阻止的消息(或消息ID)是否合理?

是。 在RESTful URI請求中提供過濾器。

每次我請求新的消息列表時,是否真的必鬚髮送整個消息發送者列表來阻塞?

是。 這個“消息發送者阻止列表”有多大? PK的短名單?

GET請求可能非常大。 如果有必要,即使聽起來像是一種查詢,你也可以嘗試POST請求。


無狀態意味著服務的狀態不會在隨後的請求和響應之間持續存在。 每個請求都攜帶自己的用戶憑證並經過單獨驗證。 但是在有狀態的情況下,每個請求都可以從以前的請求中知道 所有有狀態請求都是面向會話的,即每個請求都需要知道並保留以前請求中所做的更改。

銀行應用程序是有狀態應用程序的一個例子。 用戶首先登錄然後進行交易並註銷。 如果註銷後用戶將嘗試進行交易,他將無法做到這一點。

是的,http協議實質上是一種無狀態協議,但為了使它成為有狀態的,我們使用HTTP cookie。 所以,默認情況下是SOAP。 但是它也可以是有狀態的,取決於你使用的框架。

HTTP是無狀態的,但我們仍然可以通過使用不同的會話跟踪機制在我們的Java應用程序中維護會話。

是的,我們還可以在Web服務中維護會話,不管它是REST還是SOAP。 它可以通過使用任何第三方庫來實現,也可以由我們自己來實現。

取自http://gopaldas.org/webservices/soap/webservice-is-stateful-or-stateless-rest-soap


基本的解釋是:

服務器上沒有客戶端會話狀態。

無狀態意味著服務器不會在服務器 存儲有關客戶端會話的任何狀態。

客戶端會話存儲在客戶端上。 服務器是無狀態的,意味著每個服務器可以隨時為任何客戶端提供服務,不存在會話關聯粘滯會話 。 相關的會話信息存儲在客戶端並根據需要傳遞給服務器。

這並不排除Web服務器與維護有關諸如購物車等業務對象狀態的其他服務,而不是關於客戶端當前的應用程序/會話狀態。

客戶端的應用程序狀態不應該存儲在服務器上,而應該從客戶端傳遞到每個需要它的地方。

這就是REST中的ST來自State Transfer 。 你轉移狀態而不是讓服務器存儲它。 這是擴展到數百萬並髮用戶的唯一方法。 如果沒有其他原因,而不是因為數百萬次會話是數百萬次會話。

會話管理的負載在所有客戶端之間進行攤銷,客戶端存儲其會話狀態,服務器可以以無狀態的方式服務許多數量級或更多的客戶端。

即使對於您認為需要數十個並髮用戶的服務,您仍然應該使您的服務成為無狀態。 成千上萬的人仍然有數万人,並且會有與其相關的時間和空間成本。

無狀態是HTTP協議和一般的網絡是如何設計運行的,並且是一個整體上更簡單的實現,並且你有一個代碼路徑而不是一堆服務器端邏輯來維持一堆會話狀態。

有一些非常基本的實施原則:

這些原則並非實現,您如何滿足這些原則可能會有所不同。

總之, 五個關鍵原則是:

  1. 給每個“東西”一個ID
  2. 把事情聯繫起來
  3. 使用標準方法
  4. 具有多種表示的資源
  5. 無國籍溝通

在REST dissertation沒有關於認證或授權的內容。

因為與從非RESTful請求進行身份驗證相比,沒有任何區別。 認證與RESTful討論無關。

解釋如何為您的特定需求創建無狀態應用程序,對於來說過於廣泛

與REST相關的實現身份驗證和授權甚至更廣泛,並且通常在互聯網上詳細解釋各種實現方法。

有關此問題的意見徵求/意見將被標記為不再需要


REST非常抽象。 它有助於獲得一些好的,簡單的,現實世界的例子。

以所有主要社交媒體應用為例 - Tumblr,Instagram,Facebook和Twitter。 它們都有一個永遠滾動的視圖,您向下滾動得越遠,您看到的內容越多,時間越晚。 然而,我們都經歷過那一刻,你失去了滾動的位置,而應用程序會將你重新設置為頂端。 就像如果你退出了應用程序,那麼當你重新打開它時,你又回到了頂端。

之所以這樣,是因為服務器沒有存儲你的會話狀態。 不幸的是,你的滾動位置只是存儲在客戶端的RAM中。

幸運的是,當您重新連接時,您不必重新登錄,但這僅僅是因為您的客戶端還存儲了登錄證書尚未過期。 刪除並重新安裝應用程序,您將不得不重新登錄,因為服務器未將您的IP地址與會話相關聯。

您在服務器上沒有登錄會話,因為他們遵守REST。

現在上面的例子根本不涉及Web瀏覽器,但是在後端,應用程序正在通過HTTPS與其主機服務器進行通信。 我的觀點是,REST不必涉及cookie和瀏覽器等。存儲客戶端會話狀態的方式有多種。

但讓我們談一下Web瀏覽器,因為這帶來了REST的另一個主要優勢,這裡沒有人談論。

如果服務器試圖存儲會話狀態,它應該如何識別每個客戶端?

它無法使用他們的IP地址,因為許多人可能在共享路由器上使用相同的地址。 那麼怎麼樣呢?

它不能使用MAC地址的原因很多,其中最重要的原因是因為您可以在不同的瀏覽器上同時登錄多個不同的Facebook賬戶以及應用程序。 一個瀏覽器可以很容易地假裝成另一個瀏覽器,而MAC地址也很容易被欺騙。

如果服務器必須存儲一些客戶端狀態來識別您的身份,則必須將其存儲在RAM中的時間不僅僅是處理請求所需的時間,否則它必須緩存該數據。 服務器的內存和緩存數量有限,更不用說處理器的速度了。 服務器端狀態以指數形式增加到所有三個狀態。 此外,如果服務器要存儲有關會話的任何狀態,則必須針對您當前登錄的每個瀏覽器和應用程序以及您使用的每個不同設備單獨存儲。

所以...我希望你現在看到為什麼REST對於可伸縮性如此重要。 我希望你可以開始明白為什麼服務器端會話狀態是為了服務器可擴展性,它是焊接在鐵砧上的汽車加速性能。

人們感到困惑的地方在於認為“狀態”是指存儲在數據庫中的信息。 不,它指的是當您使用服務器時需要在服務器的RAM中存儲的任何信息。


您必須在客戶端管理客戶端會話。 這意味著您必須為每個請求發送驗證數據,而且您可能需要但不必在服務器上有內存緩存,它將身份驗證數據與身份,權限等用戶信息配對。

這種REST 無狀態約束非常重要。 如果不應用這個約束,你的服務器端應用程序將不能很好地scale ,因為維護每一個客戶端會話將成為它的致命弱點


我看到這裡的基本問題正在將SessionState混合在一起。 雖然REST指定您不應該將狀態存儲在服務器上,但沒有任何東西阻止您存儲用戶會話

在服務器上管理狀態意味著您的服務器完全知道客戶端在做什麼(他們在應用程序的哪個部分查看哪個頁面)。 這是你不應該做的。

我同意其他人說你應該保持會話存儲的最小尺寸; 雖然這是常識,但它實際上也取決於應用程序。 因此,簡而言之,您仍然可以使用緩存數據保持會話,以便在服務器上負載較少的情況下處理請求,並通過為客戶端提供臨時身份驗證/訪問令牌來管理身份驗證。 每當會話/令牌過期時,生成一個新的請求並要求客戶端使用它。

有人可能會爭辯說客戶應該更好地生成令牌。 我說這兩種方式都有效,它取決於應用程序,以及誰將使用API​​。

在服務器上保留一些敏感的會話數據應該是正確的做法。 您不能相信客戶保持購物車(例如)包含名為“isFreeGift”的字段。 這些信息應該保存在服務器上。

Santanu Dey在他的回答中提供的視頻鏈接很有幫助。 如果沒有,請觀看​​它。

只是一個側面說明:似乎所有的答案似乎忽略了一些操作可能會導致服務器負載很重的事實。 這在功耗,硬件消耗和成本(針對CPU週期租用的服務器)方面是相關的。 一個優秀的開發人員不應該懶惰地優化他們的應用程序,即使他們不支付電費和維護費用的某些租用服務器上的現代CPU上的操作可以非常快地完成。

雖然這個問題已經有幾年了,但我希望我的回答仍然有幫助。


無狀態意味著每個HTTP請求都完全隔離。 客戶端發出HTTP請求時,會包含服務器完成該請求所需的所有信息。 服務器從不依賴以前請求中的信息。 如果這些信息很重要,那麼客戶會在這個請求中再次發送它。 無狀態還帶來了新的功能。 在負載平衡的服務器上分發無狀態應用程序更容易。 無狀態應用程序也很容易緩存。

實際上有兩種狀態。 應用狀態,位於服務器上的客戶端和資源狀態。

當您實際發出請求時,Web服務只需要關心您的應用程序狀態。 其餘時間,它甚至不知道你的存在。 這意味著只要客戶端發出請求,它就必須包含服務器需要處理的所有應用程序狀態。

每個客戶端的資源狀態都是相同的,並且其適當的位置在服務器上。 當您將圖片上傳到服務器時,您會創建一個新資源:新圖片具有自己的URI,並且可以成為未來請求的目標。 您可以通過HTTP獲取,修改和刪除此資源。

希望這有助於區分無國籍狀態和各個州的含義。


無狀態與有狀態之間的主要區別是數據每次都傳回服務器。 在無狀態的情況下,客戶端必須提供所有信息,因此可能需要在每個請求中傳遞大量參數。 在Stateful中,cliet只傳遞一次這些參數,並由服務器維護,直到客戶端再次修改。

國際海事組織,API應該是無國籍的,這使得可以迅速擴大規模。





session-state