2017-08-28 129 views
1

讓我們假設有一個實體公司和一個實體國家。一個公司可以屬於很多國家,一個國家可以有多個公司。因此,對於公司而言,有一個具有不同角色的中間表成員資格。一個公司是一個國家的製造商,另一個公司是一個國家的供應商。一個國家可以擁有多個地位,如is_active等。RESTful API用於過濾的多個資源的多個查詢字符串

現在我們要從一個特定的公司取得所有國家,其中角色是製造商,國家的狀態是is_active = false。

RESTful API端點如何查找此用例?它允許過濾多個資源嗎?一些想法:

GET /companies/{id}/nations?role=manufacturer&is_active=false 

GET /memberships/{id}/nations?role=manufacturer&is_active=false 

UPDATE 也許我的問題是不夠清楚。查詢字符串參數在兩個不同的表/實體中進行查找。角色位於會員實體內部,is_active位於國家實體內部。我認爲只能在請求的資源上進行過濾。也許我可以在兩個用例中分解這個問題。

1)使用URI中的中間資源是否「更好」? 2)我們可以通過多個表/實體過濾具有查詢字符串參數的資源嗎?

+1

這完全取決於你如何實現它的API設計。 REST不關心你的URI是如何看起來的,因爲關係本身提供了URI的語義。 –

回答

1

REST不關心你用什麼拼寫標識符。編碼到URI中的任何數據都由服務器自行決定並供其自己使用。

這基本上意味着只要你的URI符合RFC 3986,你就是在做正確的事情。這意味着:

Hierarchical data屬於路徑 - 允許通用客戶端以正確的方式解析相對引用。非分層數據屬於查詢。

是否允許過濾多個資源?

其它方式圍繞 - 標識符相匹配了一個單一資源可加載/濾波器狀態,從多行數據。

GET /companies/{id}/nations?role=manufacturer&is_active=false 
GET /companies/{id}/nations?role=manufacturer&is_active=true 

這是兩個不同的資源;它們碰巧被相同的參數化查詢支持的事實是一個實現細節。

查詢字符串參數在兩個不同的表/實體中進行查找。

這是一個實現細節。就API消費者而言,您只需將準備好的文檔從關鍵值存儲區中取出即可。

這就是要點 - 這裏 - 即使底層實現需要更改,API也應該是穩定的。將您的集成界面緊密結合到當前的數據模式使得向後兼容的更改變得更加困難。

我認爲只允許在請求的資源上進行過濾。

不可以。就REST而言,整個URI是一個標識符。客戶端使用該URI來訪問和操作資源。接口後面的資源實現看起來完全沒有REST約束。它可能是一個文檔存儲,一張桌子,很多桌子,一個第三方服務,所有這些的組合......

您用於提供當前表示的服務器端框架可能會關注 - 有些標識符比其他標識符更適合您的路由策略,但框架可能會限制您將數據存儲在一個地方。但這些都只是實施細節。 REST不關心。

我們可以通過多個表/實體過濾具有查詢字符串參數的資源嗎?

「過濾器的資源」是不太使用權的拼寫,因爲它資源(即REST關心的事情),與您的數據模型混淆你的整合。

單個資源的表示是否可以根據存儲在多個表中的數據創建?當然。資源是否可以限制在滿足某些過濾規範的那些表中?當然。是否有限制哪些過濾器可以應用於哪些表?

吉姆·韋伯:

URI不映射到域對象 - 這違反了封裝....你應該期望有很多很多的資源在集成領域比你做的業務對象的業務領域。

+0

@DehMotth廣告1)沒有對錯的URI裏面關於邏輯,因此這個問題是相當的意見爲主。廣告2)什麼阻止你這樣做?你可能也有一個看起來矩陣參數,在那裏你可以的各分段直接指定perameters而不是在末端附加它們。雖然,因爲您已經指定了一個具體的ID,所以我不確定在該特定情況下進一步過濾機制的用處 –

0

下面是在SlashDB中實現的一個有見解的答案。

考慮這種情況,這是非常類似於你:

軌道 - < PlaylistTrack> - 播放列表

的軌道可以在許多播放列表和播放列表通常是由許多曲目。下面的網址是可以點擊的,並會顯示出資源的HTML表示:

下面是URI的播放列表「經典」:

https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical

現在,讓我們跨越到直通表PlaylistTrack

https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical/PlaylistTrack

由於PlaylistTrack有關係的跟蹤,我們可以添加,作爲最後一段:

https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical/PlaylistTrack/Track

您可以選擇遵循相同的模式。一般實現時,它將允許非常驚人的過濾和遍歷數據模型。

例如,讓我們找到了在該播放古典曲目發票,但只有來自法國,奧地利和意大利的那些,只用3到10元之間總的人。

https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical/PlaylistTrack/Track/InvoiceLine/Invoice/BillingCountry/France,Austria,Italy/Total/3..10