2017-03-19 111 views
2

在REST API,它被認爲是一個很好的做法來處理排序,篩選和使用URI查詢參數,如集合分頁:高級尋呼的REST API設計排序和過濾

GET /employees?offset=30&limit=15&name=Mary&sort=-surname 

不幸的是,在一些「高級」情況下,參數的數量可能會「爆炸」,因此這種解決方案不再可能。

回到前面的例子,假設我們想在其他許多領域應用一些更復雜的過濾器(例如:地址包含「NY」,年齡> 30,年齡< = 40,(婚姻狀態是「已婚」和工資< 100000USD)或(婚姻狀況是「離婚」和工資> = 100000USD),和許多其他...)。

顯然,在這種情況下,一組簡單的查詢參數是不合適的。

如何這樣的情況應該設計?也許客戶端應該發送一個包含代表查詢的結構化數據的POST?關於如何設計此類查詢,是否有任何或多或少的標準協議?

謝謝!

+0

您可以定義「高級」病例嗎?一般來說,你應該能夠量化參數,所以參數的數量不會「爆炸」。 – meyer9

+0

將子句與布爾運算符結合使用(如示例中所示)可能會導致非常大的過濾器。這需要大量的查詢數據的另一個基本的例子可能是「中」操作符,如:名稱是(「瑪麗」,「JHON」,「卡爾」,...) –

回答

1

一種方法是讓搜索過濾器,一個REST資源意味着創造新的REST方法:

  • POST /filters,期待一個體過濾器,例如(marital status is "married" AND salary<100000USD) OR (marital status is "divorced" AND salary>=100000USD)並返回該搜索的唯一ID,以及(避免往返到服務器)的第一批成果,並鏈接到下一個結果
  • GET /filters/<id>/<offset>,返回的搜索id結果從offset
+0

太好了!這將集合的過濾轉換爲創建過濾器。我喜歡它,因爲POST動詞有效地用於創建新資源(過濾器!),然後使用GET動詞獲取其屬性(過濾器的結果)。看起來好! –

+1

是的,確切地說。過濾器成爲您的應用程序的一等公民。您的應用可以將它們用於向用戶呈現「你最後的搜索」。 –

1
開始

你有沒有嘗試過濾一個身體?

{ 
    "age": { 
    "$gte": 30, 
    "$lte": 40 
    }, 
    "status": { 
    "$in": [ 
     "Divorced", 
     "Single" 
    ] 
    } 
} 
+0

這是我在思考解決方案,但因爲我們使用的是POST,而我們應該在語義上使用GET我不喜歡它。我喜歡的東西,不偏離太多從通常的REST「良好做法」 ... –

+0

該解決方案是好的,如果與一個由@Adam,http://stackoverflow.com/a/42893377/建議合併1288109:這個想法是使用POST而不是資源本身,而是創建一個新的「過濾器」實體。 POST/employees /過濾器 –