2017-08-25 55 views
1

我正在爲一個像「jobs」這樣的概念設計一套RESTful API。作業的模式是這樣的:這兩個RESTful API設計哪個更好?

Job: { 
    id: 1, 
    name: "Brew coffee", 
    status: "paused" | "running" | "finished", 
    progress: 0.75 
} 

及以下RESTful的原則,對/api/jobs通過HTTP動詞客戶CRUDs工作。例如,initalizing新工作

POST /api/jobs 
-------------- 
Request body: { 
    name: "Push button" 
} 
--------------- 
Response status: 200 OK 
Response body: { 
    id: 2, 
    name: "Cook dinner", 
    status: "running", 
    progress: 0 
} 

和訪問這個工作

GET /api/jobs/2 
-------------- 
Request body: {} 
--------------- 
Response status: 200 OK 
Response body: { 
    id: 2, 
    name: "Cook dinner", 
    status: "running", 
    progress: 0.5 
} 

我的問題是,我應該怎麼設計的API,如「暫停」的行動?關上我的頭我在二個 選項之間進行考慮:

一種選擇是將其設計爲PATCH請求,並宣佈直接結束狀態我想,像這樣

PATCH /api/jobs/2 
-------------- 
Request body: { 
    status: "paused" 
} 
--------------- 
Response status: 200 OK 
Response body: { 
    id: 2, 
    name: "Cook dinner", 
    status: "paused", 
    progress: 0.65 
} 

的另一種選擇是將其設計爲POST要求,並聲明行動我想,像這樣

POST /api/jobs/2 
-------------- 
Request body: { 
    action: "pause" 
} 
--------------- 
Response status: 200 OK 
Response body: { 
    // same as above 
} 

考慮在未來,我可能會執行其他操作,如「簡歷」,「優先級排序」,「優先排序」等,您認爲哪兩個選項更好?還是有更好的做法?

+2

你問的問題的答案並不重要......但如果來自GET/api/jobs/2的響應沒有告訴你答案,那麼它不是REST。很抱歉讓所有的Roy Fielding在你身上,但是如果你真的不在乎它是不是REST,那麼只要做一些符合你的要求的事。 –

回答

2

我的問題是,我應該如何設計一個像「暫停」這樣的動作的API?

你會如何設計一個網站來支持像「暫停」這樣的動作?

你可能有一個登陸頁面開始,客戶端可以得到的。您返回的響應可能會表示該作業的當前狀態,並且還會包含鏈接,並附帶用戶可理解的語義標註。其中之一是「暫停」行動。

繼暫停鏈接可能會得到一個形式,與一些輸入字段,每個語義標註,可能默認值的每個字段的。客戶端將替換輸入字段中的部分或全部值,並提交表單。

這將POST表單數據到您指定的終點,此時您的實現會去調用暫停副作用,與描述的結果表示響應。

這是遵循的模型。 REST-API的實現是一個適配器,它使您的服務看起來像一個通用網站。

這裏的關鍵思想是,客戶端不需要預先知道的URI來使用,或HTTP方法的使用,因爲這些信息被編碼到由服務器提供的鏈接的表示。客戶只需要識別並遵循鏈接。

POST是;自HTTP/1.0以來,HTML客戶端一直在使用它。 PUT和PATCH也是罰款,如果你想提供一個「遠程創作」接口。

您可以查看Rest Causistry。確保你閱讀了REST真正討論的地方。這也是有用的審查Fielding的Paper Tigers and Hidden Dragons ...

我也應該注意到,上述尚未完全RESTful的,我至少是如何使用的術語。我所做的只是描述了服務接口,它不過是任何RPC。爲了使其成爲RESTful,我需要添加超文本來介紹和定義服務,描述如何使用表單和/或鏈接模板執行映射,並提供代碼以有用的方式組合可視化。

Matt Timmermans'comment comment it right;如果您只是記錄客戶端自己導航的一堆斷開連接的端點,那麼您不會執行REST。並且在您不需要允許客戶端和服務器獨立發展的解決方案中,這也是罰款

REST適用於跨多個組織的長期基於網絡的應用程序。如果您沒有看到這些限制條件,那麼請不要使用它們。

跟進的評論:

看來,這種類型的基於導航的API的組織是非常靈活的,如果我們是在談論一個人操作的客戶端(如瀏覽器),但我不太確定是否可以輕鬆地編寫一個可以調整服務器端更改的自動客戶端。 「...添加超文本來介紹和定義服務,描述如何使用表單和/或鏈接模板執行映射...」聽起來完全是以人爲本的。

我也遇到了麻煩。

沒有人聲稱,使用REST API,機器消費者將奇蹟般地能夠理解語義 API中的更改。如果我們想要支持現有的客戶端,那麼我們在服務器上所做的更改必須以向後兼容的方式完成。但是 - 這是關鍵的想法 - 語義和表示之間存在額外的間接層。

要選擇一個簡單的例子,在帶分頁的API中,消費者需要了解next page的語義;它需要能夠請求客戶處理下一頁鏈接。但它並不需要知道如何表示該鏈接,鏈接機制,或URI,或任何類似的東西。 通用瀏覽器模擬知道這些位,併爲消費者做所有這些工作。

還有一個消費者需要了解的協議;但該協議使用鏈接表示,而不是URI。

+0

謝謝。關於RESTful設計的一個問題是:如果我們談論的是一個人工操作的客戶端(如瀏覽器),似乎這種基於導航的API組織非常靈活,但我不太確定如何編寫自動客戶端可以調整服務器端的更改。 「...添加超文本來介紹和定義服務,描述如何使用表單和/或鏈接模板執行映射...」聽起來完全是以人爲本的。 – trVoldemort

1

這個問題有幾個方面,並且選擇的選項取決於您想要設置哪些事項作爲優先級。

問題1)從REST的角度來看哪個更好?

從嚴格的REST觀點來看,PATCH{ "status": "pause" }是正確的。 REST是重新呈現狀態轉移。而這個解決方案最嚴格地符合那個。

問題2)我應該使用面向「行動」的端點嗎?

從嚴格的REST觀點來看,答案是否定的。然而,這就是說,實際上有很多很好的理由來做到這一點。 嚴格 REST API實現的一個副作用是您的API可以開始看起來並且像Web訪問的數據存儲一樣,而不是一個獨立的服務。發生這種情況時通常會發生越來越多的邏輯遷移到API的客戶端......在客戶端代碼中將複雜的操作實現爲對多個REST操作的多次調用。

這通常不是你想要的,雖然它可以通過精心製作的API來避免,但它通常不是。

問題3)什麼是最佳實踐?

沒有一個,至少不客觀。具有不同目的的不同API更好地適應REST或面向操作的調用機制。也就是說,我很少遇到一個完全RESTful的API,並且沒有面向動作的例程......而且大多數時間都隨着時間的推移而漂移......如果除了大多數API需要某種搜索功能之外沒有其他原因,嚴格的REST沒有爲此提供規定。

所以,到最後,我的建議是,使用REST,它的工作原理,它會讓你的API爲其他人更容易上手...並用行動導向終點時動作不適合的REST的概念很好。最好有一個易於理解的動作端點,而不是很難掌握REST動作,這會觸發幕後的神奇事物。

但是,這就像...我的意見,男人。

+0

但請確保不要使用PATCH和application/json作爲請求的有效載荷。 –

+0

照顧詳細? – JayKuri

+0

請參見 - 僅針對爲PATCH設計語義的有效負載媒體類型使用PATCH。這不適用於application/json。 –