2016-11-06 69 views
7

假設我想創建一個RESTful接口,並且我想根據它們的IDs使用foo。這裏沒有新東西:返回也是集合的資源表示的最佳實踐

  • GET /api/foo1返回foo1的表示(例如使用JSON)。
  • DELETE /api/foo1刪除foo1

現在讓我告訴你,「富」是一個集合類型的事情。所以,我希望能夠以「條」添加到「富」:

  • PUT /api/foo1/bar3增加bar3foo1
  • GET /api/foo1/bar3返回foo1的表示形式。
  • DELETE /api/foo1/bar3foo1刪除bar3
  • DELETE /api/foo1共刪除foo1

現在問題仍然存在:GET /api/foo1做什麼?它是否像我最初在這個問題中假設的那樣簡單地返回foo1的表示形式?還是它返回一個酒吧列表?或者它是否返回表示foo1既是foo1的描述以及包括所有包含的酒吧列表?

還是應該GET /api/foo1僅僅返回foo1表示如我在開始時假定,並要求PROPFIND請求,要求列內foo1(通過WebDAV的所採用的方法)的棒?但是爲了保持一致,我是否不必將所有其他列表類型的功能都更改爲PROPFIND,這直接違背了成千上萬的REST教程,這些教程使用GET /api/foo1來列出內容?

回答

2

webdav的語義從來沒有真正符合RESTful接口的習語。

理論上,GET應該檢索資源狀態的表示,並且PROPFIND應該用於檢索集合的成員。

所以,你應該這樣做:

  • GET/API/foo1/- 回報foo1的狀態只
  • PROPFIND/API/foo1/- 返回foo1

成員大多數如果你告訴他們使用PROPFIND,前端開發人員會嚇壞了,儘管它在瀏覽器js實現中完全支持。

我個人使用WebDAV/JSON網關,其中請求使用REST風格的成語製成,但排到我的WebDAV實現

例如,我會做到這一點:

GET /api/foo1/_PROPFIND?fields=name,fooProp1,fooProp2 

這將返回

[ 
{ name : "bar1", fooProp1: "..", fooProp2 : ".."}, 
{ name : "bar2", fooProp1: "..", fooProp2 : ".."} 
] 

這種方法的一個優點是客戶端可以控制返回的json屬性。這很好,因爲豐富的API會有很多屬性,但在大多數情況下,客戶端並不需要所有這些屬性。

1

RESTfull API中的路由及其操作完全由開發人員設計。開發者在請求特定路線時決定返回什麼,例如GET /api/foo1

而且開發者應該設計每條路線,包括/api/foo1/bar。沒有關於特定路線應該做什麼的具體規則。如果您的API是一個開源項目,請爲每條路線制定清晰明瞭的文檔。

不要浪費你的時間思考舊的學校策略。

3

經過一番思考,我認爲從RESTful的角度來看最好的概念性解釋是,通常這個「東西」與它的「集合」不是一回事。因此,在WebDAV世界中,directory/可能與保存其文件的東西是一樣的,但在RESTful世界中,我可能會爲包含的文件單獨使用directory/files/子路徑。這樣我就可以分別操作與保存的文件不同的目錄。

考慮一個包含穀倉的農場的RESTful API。端點farm/api/barns/可能會返回一列穀倉,其中一個穀倉將是farm/api/barns/bigredbarn。天真地我會認爲檢索farm/api/barns/bigredbarn/會給我提供一個穀倉裏的動物列表,這就是引發這個問題的原因。

但穀倉裏的動物真的只是大紅穀倉的一個方面。它可能包含車輛和乾草:

  • farm/api/barns/bigredbarn/animals/
  • farm/api/barns/bigredbarn/vehicles/
  • farm/api/barns/bigredbarn/haybales/

有了這個方法,我所面臨的困境並不存在。

+0

我喜歡你的方法。事實上,這是相同的行爲,真正面向對象的語言實現對數組或對象列表: Array對象的屬性:長度,尺寸,只讀 陣列方法GetValue - 返回一個項目 List對象的屬性:頭部,當前 列表方法GetEnumerator - 返回一個對象,該對象又將返回項目 –