2016-12-06 81 views
0

我正在開發一個相當複雜的帶有Angular2前端的Web應用程序。我想維護所有客戶端與服務器之間的通信,使用基於Node.js的RESTful API來傳遞JSON對象。使用REST API管理複雜應用程序的狀態

但是,我對REST應該是無狀態的要求有些困惑。在服務器端存儲或生成相當多的數據,並將其存儲在客戶端並將其附加到每個請求都會產生相當大的開銷。

例如:有數百個與特定用戶相關的權限(即哪個資源可以在什麼級別訪問)。通過未加密的客戶端執行這些權限是一個明顯的安全問題;用每個請求重新提交所有的數據(加密)感覺很奇怪。在每次請求時從數據庫刷新它們都會導致性能下降。

我的意思是,當然至少有一些類型的訪問令牌,在身份驗證時生成,必須通過每個請求傳遞給服務器。我只是假設我會生成一個不可猜測的會話ID(僅在成功驗證時),並將它以http-only(限制JavaScript訪問),安全(強制使用https)Cookie和使用此cookie傳遞給客戶端在服務器端保持一些節約的會話狀態(如權限)。但是,這種做法似乎在REST世界中被忽略了?是一個有狀態的RESTful API是一個矛盾的,一個異端?

回答

2

不過,我對此感到REST應該是無狀態的要求有些困惑

如有疑問,請查看論文 - 在這種情況下,菲爾丁是什麼stateless意味着非常清楚:

通信本質上必須是無狀態的,這樣每個從客戶端到服務器的請求都必須包含理解請求所需的所有信息,並且不能利用任何st在服務器上存儲上下文。會話狀態因此完全保留在客戶端上。

換句話說,沒有代詞。他在描述Client-Stateless-Server architecture

時描述了主要優點,這些約束改進了可見性,可靠性和可伸縮性的屬性。可見性得到改進,因爲監控系統不必超越單個請求數據,以確定請求的全部性質。可靠性得到改善,因爲它減輕了部分故障恢復的任務。由於不需要在請求之間存儲狀態,可擴展性得到了改進,使服務器組件可以快速釋放資源並進一步簡化實施。

客戶端無狀態服務器的缺點是它可能會通過增加一系列請求中發送的重複數據(每個交互開銷)來降低網絡性能,因爲這些數據不能在共享上下文中留在服務器上。

我們不假定服務器託管純函數; 當然服務器端存在狀態。在大多數情況下,使用REST api的目的是提供一個接口,以適應Web的服務器端狀態(以任何形式)。

例如:有幾百個與某個用戶相關的權限(即哪個資源可以在什麼級別訪問)。通過未加密的客戶端執行這些權限是一個明顯的安全問題;用每個請求重新提交所有的數據(加密)感覺很奇怪。在每次請求時從數據庫刷新它們都會導致性能下降。

服務器緩存一些自己的狀態沒有什麼根本性的錯誤,作爲優化來提高後續調用的響應時間。這一切都隱藏在界面後面,並且完全不影響REST約束。 (如果下一個請求被路由到另一個服務器,您將得到緩存未命中和第二次查找,但這些不會以任何方式改變請求的含義。)

但是服務器不應該製作對客戶狀態的任何假設,因爲它不能看到發生了什麼;在沒有通知服務器(後退按鈕,請求由中間組件處理,請求由同一服務器的其他副本管理)的情況下,客戶端狀態可以改變。

另一方面,客戶端在發送任何給定消息時確切知道客戶端處於什麼狀態;它管理會話。任何相關的會話數據都會被客戶端複製到請求中,服務器將處理請求內容及其自身狀態,而不會記錄先前的請求。