2016-10-04 51 views
3

我正在構建一個REST API,並且我有一些關係使得我的鏈接非常長。它們對我來說很有意義,但它是一團糟。我不知道處理這個問題的最好方法是什麼。有這麼長的鏈接有問題嗎?我是否違反了這些原則?我應該如何處理這樣的關係?在REST API中處理非常深的關係

下面的例子是有點人爲的,但它說明了我想要做的。

一個公司有許多部門。每個部門有很多僱員。每個僱員可以有許多計算機。每個計算機可以有很多文件就可以了。

GET的路徑特定的文檔將是:

/companies/:companyId/departments/:departmentId/employees/:employeeId/computers/:computerId/documents/:documentId 

每個ID是該層內的全局唯一 - 沒有兩個文檔ID將是在整個系統中的相同,但一個文件ID可以是與員工ID相同。

這對我來說很有意義,因爲每一層只與上面的一件事有關。一個部門將只屬於一個公司,一個員工只屬於一個部門,一部電腦只屬於一個員工,而一個文件只屬於一部電腦。

我可以將它們分解爲單獨的端點,例如/computers,但是我怎麼知道在哪裏破壞它們?爲什麼我會選擇/computers作爲端點,而不是/employees/:employeeId/computers

+0

**是全球唯一的** documentId **嗎? – JonSG

+0

@JonSG是的,它在所有文檔ID中都是唯一的。我編輯了這個問題來澄清。 – vaindil

+2

我的意見在這裏,但我覺得沒有必要在API中表示它們的層次結構。你在一個例子中說明的那個,但可能有很多其他的。我覺得你的API應該簡化爲**/document/[id] **。同樣,如果employeeid是全球唯一的,那麼** employee/[id] **。爲什麼讓消費者知道員工和部門是否想知道具有已知ID的文件內容?另一方面,初始投貼是一個不同的問題,因此可能需要層次結構。是否需要支持「完整」動詞集,或者獲得足夠的? – JonSG

回答

2

在這個例子中,我將把這些資源中的每一個都移動到頂層。每個頂級資源都可以有下一個「級別」作爲成員。所以,

/companies 
/companies/{id} 
/companies/{id}/departments 
/departments 
etc.. 

我只會添加子資源,如果它實際上是最終用戶需要操縱集合的內容。

深度嵌套的資源是有問題的。在3個月內,如果您的企業要求找到所有員工,而不管部門爲公司{id}工作,會發生什麼情況?將員工作爲頂級資源,您可以添加對GET /employees?companyId={id}的支持。在上面介紹的設計中,您的選擇都很糟糕。在您正式確定嵌套結構時,您放棄的資源之間的關係具有很大的靈活性。

至於你的一些具體問題:

我建立一個REST API

REST是對URI設計的主題完全無關。

我有一些關係讓我的鏈接很長。它們對我來說很有意義,但它是一團糟。 [..]有這麼長的鏈接是一個問題嗎?

最終用戶將希望永遠不會打字這些。如果你的API真的是RESTful的,則客戶端將使用您傳回的聯繫,他們不應該在任何輸入它們。在一個RESTful系統中,我期望「我有一些X」關係被保存在一個鏈接中,而不僅僅是通過URI的形式記錄。我同意他們是長期的,我會根據上述原因改變他們,但我不認爲你的具體擔憂是改變他們的好理由。

我違反了這些原則嗎?

不是我所知道的。

+0

我完全同意REST是URI不可知的,並且過分強調所謂的乾淨URI設計。儘管如此,我也不會將每個子資源都更改爲頂級資源。我個人的偏好是如果資源能夠自己「生存」,就將資源轉換爲頂級資源。一個部門與一個公司緊密相連,一個員工仍然會在沒有公司的情況下生活,但它不再是該公司的員工,因此我將它作爲子資源。另一方面,計算機仍然是一臺計算機,無論公司如何,因此適用於頂級資源。 –

+0

@RomanVottner所以在這個例子中,你只有部門作爲子資源?如果你能確保緊密的耦合是永恆的,我不會不同意這種方法。如果該業務規則發生變化,儘管... –

+0

員工也耦合到公司,否則它不會是員工。如果員工退出公司並且沒有任何生命危險發生在她身上,她仍然會生活,但不會成爲該公司的員工。即使業務規則發生變化和/或部門合併/分裂,一個真正的RESTful客戶端也不會因爲他們僅僅從以前的響應中學習而中斷。與URI相關的問題總是傾向於自以爲是的答案,儘管SO社區並不熱衷於關閉這樣的問題IMO。 –