2014-10-29 104 views
1

我正在設計一個大型的報告數據集合的REST風格的API,我想通過一組複雜的參數,如下面的代碼塊。我在爲這個端點使用POST和GET之間進行辯論。團隊成員似乎贊成GET,但我不知道通過這個數據量作爲GET參數,最好的辦法,到目前爲止是有一個GET參數稱爲像jsonparams,將有以下所有JSON編碼的最佳方式REST風格的API設計的爭論:複雜的查詢寧靜的端點

{ 
    "filters": 
    [ 
     { 
     "field": "metric-name", 
     "gt": (float/int), 
     "lt": (float/int) 
     }, 
     { 
     "field": "metric-name-2", 
     "gt": (float/int), 
     "lt": (float/int) 
     } 
    ], 
    "sort": 
    [ 
     { 
     "field": "metic-name", 
     "order": "ASC"/"DESC" 
     }, 
     { 
     "field": "metic-name-2", 
     "order": "ASC"/"DESC" 
     } 
    ] 
    "limit": 100, 
    "offset": 0 
} 
+0

可能的重複[什麼時候應該使用GET或POST方法?他們之間有什麼區別?](http://stackoverflow.com/questions/504947/when-should-i-use-get-or-post-method-whats-the-difference-between-them) – 2014-10-29 22:29:59

+0

這是一個比這更概念 – dismal 2014-10-29 23:04:25

回答

2

如果要將數據添加到資源或創建資源,請使用POST。 GET是獲取已經存在的資源,而不是改變資源的狀態。

如果使用基於瘋狂的序列化的基於GET參數的請求進行某種percived簡單操作的參數,那麼您將不會接受REST。

現在,如果您僅檢索資源(不創建),請使用GET。雖然我更喜歡人類可壓縮的參數,但並不是必需的。如果你的情況是100%恢復,你可以整組編碼成成一個巨大的編碼PARAM字符串,但我建議做類似的東西,至少分裂出來有點改進的理智:

/resource?filters=urlencoded_filter_array&sort=urlencoded_sort_array&offset=0&count=100 

或者你可以去更明確,如:

/resource?filter1=urlencoded_filter_json&filter2=urlencoded_filter_json .... sort2=urlencoded_sort_json&offset=0&count=100 

或最後(我的最愛)完全明確設定爆發則params的

/resource?filter1_field=bah&filter1_gt=1.0&filter1_lt<2&filter2_field=boo&filter2_lt... 

我喜歡最後一個,因爲沒有encodein g /解碼json,然後url編碼整個json字符串。這種格式很容易解讀訪問日誌和故障排除。它也是非常緩存的,即使參數順序被改變了,一些代理緩存仍然可以工作,而在json對象中編碼一些過濾器,如果它們被移動,它們看起來像完全不同的值,就代理而言。對我來說,這是最友好的(如果這是有道理的),即使前兩個例子是很好的REST GET請求。

解析參數名稱的附加工作並不是那麼大驚小怪。一個簡單的方法可以將json轉換爲參數字符串,另一個簡單的方法可以從顯式filter1_xyz格式中重新提供json對象的水合。

+0

你會如何解決複雜參數的問題? – dismal 2014-10-29 22:55:48

+0

@dismal如果你正在創建一個資源,你可以傳遞json對象作爲帖子正文。 – Ray 2014-10-30 14:34:24

+0

@dismal查看我更新的答案。如果你沒有改變任何東西,只是過濾結果,你可以使用get。 – Ray 2014-10-30 15:00:57

4

POST是用於任何未通過HTTP標準化的操作的方法。檢索通過GET方法進行標準化,因此使用POST檢索與潛在資源相對應的信息永遠不會是RESTful。從理論上講,無論你的URI變得多麼複雜,你都應該使用GET。

但是,由於您正在執行的查詢中沒有單個資源,您可以執行GET操作,所以使用POST似乎很好,只要您知道缺點並且文檔是清楚它。坦率地說,我認爲使用POST比將該有效負載編碼爲JSON + base64並將其作爲純粹查詢字符串發送純粹得多。

使用POST的真正問題是當人們以避免或阻止使用真實URI的方式使用它時。這似乎不是你的問題,因爲你有一個有效的URI集合,但你的查詢的語義太複雜,不容易表達。

如果您決定使用GET,那就有一個問題。儘管HTTP規範沒有對URI進行限制,但大多數實現都是這樣做的,如果需要將所有這些參數作爲查詢字符串提供,您可能會達到此限制。在這種情況下,只要從應用程序中分離出來,就可以避免底層實現的侷限性。做你想做的事的慣例是使用POST方法和上面描述的有效載荷,以及X-HTTP-Method-Override: GET標題。

+0

我打算和GET一樣在Ray的回答中,希望我不會遇到任何URI限制! – dismal 2014-10-30 18:16:21

+0

正如我所說,理論上這是正確的做法。如果它被採用是因爲它適用於你的情況,而不僅僅是純粹主義,我完全贊成。 – 2014-10-31 02:05:36