讓我們假設我有一個對象,該對象在我的應用程序中作爲REST資源公開。該對象具有許多字段幷包含許多其他對象,包括關聯的集合。像這樣的事情,但想到要大得多:REST資源的動態表示
Customer
List<Order> orders
List<Address> shippingAddresses;
// other fields for name, etc.
Order
List<Product> products
// fields for total, tax, shipping, etc.
Product
// fields for name, UPC, description, etc.
我在API暴露客戶爲/customer/{id}
我的一些客戶將要爲每個訂單的每一件產品的所有細節。如果我遵循HATEOAS,我可以提供鏈接以獲取產品詳細信息。這將導致n + 1呼叫該服務,以在客戶的訂單內填充產品。另一方面,如果我總是填充它,那麼許多客戶端會收到一些他們不需要的信息,我會做大量不需要的數據庫查詢。
如何根據客戶的需求允許我的資源的客戶表示?
我看到幾個選項。
使用Jackson的JsonView註釋事先指定使用的內容。來電者要求適合他們的觀點。即
/customer/{id}?view=withProducts
。這需要我在編譯時指定所有可用的視圖,並不會那麼靈活。允許呼叫者請求在請求中填充某些字段,即
/customer/{id}?fields=orders,firstName,lastName
。這將需要我有一些處理程序可以解析fields參數,並可能使用反射來填充東西。聽起來對我來說超級混亂。你對子資源做了什麼。我能做fields=orders.products.upc
並以這種方式加入集合嗎?聽起來就像我試圖在REST或其他東西上編寫hibernate一樣。按照HATEOAS,並要求客戶端進行百萬次HTTP調用,以填充他們需要的東西。對於那些不想在大多數情況下填充物品的人來說,這種方法非常有效,但對於試圖展示訂單細節總結或其他類似內容的人而言,這會很昂貴。
具有獨立的資源,爲每個視圖...
其他?
根據我的經驗,沒有以下id的'/ customer'會給出這個列表,'/ customer/{id}'是你將它縮小到單個客戶的方式,但這只是一種風格。這是'包含=實體'的東西,這是有趣的部分。這意味着我基本上只有2個選項,一個充分充實,另一個只包含字段。我認爲這幾乎不夠靈活,特別是如果某些相關集合需要昂貴的操作來填充。 – digitaljoel
那麼不是說你是否想包含某個實體,你可以通過說出你想包含哪個實體來解決它。/customers/{id}/orders /?products = yes&productdetails = yes和/ customers/{id}/orders/{id}只會給你一個帶該id的準系統訂單。 –
是啊,那基本上是我的#2。聽起來像沒有這個魔術彈頭。 – digitaljoel