2015-10-26 142 views
4

我確信這個話題一定已經被覆蓋掉了,所以我很高興指出任何我可能在搜索時錯過的文章等。主要/詳細信息與REST

我需要實現一個非常簡單的REST API來添加和檢索主/明細關係中的記錄。我的兩個選項如下:

OPTION 1

POST /master 
POST /master/[id]/details 
GET /master/[id] 
GET /master/[id]/details 

的觀光

  • 感覺更 'REST風格'
  • 可以找回細粒度數據表現

CONS

  • 沒有至少一個細節,主人沒有意義。如何處理原子性?如果細節在添加時失敗,則在主體上補償DELETE?
  • 檢索主/細節需要多方通話設置

OPTION 2

POST /master_and_details 
GET /master_and_details/[master id] 

的觀光

  • 易於管理原子

CONS

  • 更復雜的結構來管理
  • 的GET必須返回整個結構(不總是有效的)
  • 不會覺得很 'REST風格'

感謝, 約翰

+0

REST或多或少的決定選項1,選項2只是一個普通的舊的http api –

回答

2

REST或多或少地決定選項1,選項2只是一個普通的舊的http api。

您的陳述說,如果沒有至少一個細節,主人沒有任何意義可能是錯誤的。你不知道未來聰明的開發者將如何使用你的api。你可以猜到,但你並不知道。

如果您自己確實需要複合解決方案,則可以始終在更高級別添加一個接口,調用兩個單獨的接口並返回複合對象。

選項1允許微服務實現的可能性 - 或者至少將關注點分離爲兩個可分離的對象。選項2本身不會。

+0

謝謝。瞭解開發者可能會在未來某個時候獨立使用這些資源。這種結構爲此敞開了大門,但我仍然需要確保這種特殊用法的原子性。我可以編寫一個封裝器,就像你說的編排桅杆和詳細的POST文件一樣,但是如果它們失敗就需要進行補償,這意味着需要DELETE服務。你會建議一個DELETE主和級聯,或單獨的DELETE服務將是最好的?同樣,單獨的服務感覺更「RESTful」,但如果必須回滾多個詳細信息記錄,則需要更多工作來進行補償。謝謝。 – John

+0

其實,要做到這一點,你需要考慮的不僅僅是api是否寧靜。你有沒有讀過Vaughn Vernon的實施域驅動設計? http://www.amazon.co.uk/Implementing-Domain-Driven-Design-Vaughn-Vernon/dp/0321834577 –

2

至少出於爭論的緣故,冒着我微薄的聲譽冒險,我會冒險採取第三種方法。

你會有兩個資源:主和細節。(不是「細節」,除非你想完全複數,在這種情況下,你會有「主人」和「細節」)。主人的代表將包括收集細節,或者(更好)將關係與細節聯繫起來。對於該鏈接關係考慮http://tools.ietf.org/html/rfc6573

因此,主人的GET包括(直接或間接通過關係)細節的集合。 master的POST/PUT也可以通過它們存在於表單數據中的POST/PUT細節成員。

任何細節也可以是獨立於主人的GET/PUT/POSTED。在這裏,設計在某種程度上取決於細節是否有自己的主鍵,與使用主鍵的組合鍵有關。如果它有自己的主鍵,那麼你可以有:

GET /detail/{detailKey} - gets specific detail 
POST /detail - creates new detail 
GET /master/{masterkey}/detail -- gets all details for master 
GET /master{masterkey}/detail/{detailkey} -- get specific detail 

顯然,在POST上,數據必須包含主鍵。

您會看到有多個URI用於獲取詳細信息。我不認爲這是錯誤的,但它確實引入了一些含糊之處:如果detailKey實際上不是masterKey的孩子,那麼你是404嗎?我會說是的。

如果詳細信息使用組合鍵,則不能獨立於主服務器進行GET,因此不支持上面顯示的第一種形式。此外,在上面最後一個示例中使用的{detailKey}將是主內部的詳細項目的標識符(通常是序列號)。

0

我肯定會去選項1,因爲選項2與REST無關。但這並不意味着,你需要使用多個查詢來獲得Master + Detail
由於Detail屬於Master(因此它是其中的一部分),在我看來,查詢Master時,返回MasterDetail是完全可以的。
您也可以考慮使用參數來控制是否發送Detail或不。
因此,您可以使用GET /master/1?detail=true而不是執行GET /master/1
對於POSTPUT或多或少會起作用。只是沒有查詢參數,您的身體中有一個關於Detail的「部分」。 一種使用JSON示例:

{ 
    "data": { 
    "name": "master", 
    "detail": [ 
     { 
     "name": "detail1" 
     }, 
     { 
     "name": "detail2" 
     } 
    ] 
    } 
} 

POST與此數據可以創建與name 「主」 和2個Detail S表示這個Master一個Master

正如@ElroyFlynn之前所述,Detail也可以在沒有Master的情況下訪問,如果這樣做的話。
想想Thread s和Post s的論壇。 Usualy a ThreadMaster,並且每個PostDetail。但是如果你想搜索最近一小時的所有Post,你一定要直接查詢帖子(查詢可能類似於GET /post?max_age=1h)。

另外我不同意,一個Master沒有Detail不認識。有些情況下,如果不是這樣,但是在論壇的情況下,自己製造一個Thread
對於atomicity
這取決於情況:如果你刪除User你通常保留他的Post(甚至在這裏在StackOverflow)。如果您改爲刪除Thread,我想可以刪除Post