2011-06-30 8 views
2

比方說,我有一個旅行計劃應用程序,並且每次旅行都由「路徑」資源(例如,表示要驅動的路線)組成一系列點。我可以用CRUD操作,像這樣(只是一個例子)請求這些資源:你如何可以同時創建和刪除?

POST /trips/1234/paths 

<Path> 
    <Point>32,32</Point> 
    <Point>32,34</Point> 
    <Point>34,34</Point> 
</Path> 

DELETE /trips/1234/paths/3 

現在考慮,我希望能夠以一個路徑分爲兩路。在aobve的例子中,我可能想要選擇點(32,34)進行分割,這將導致兩條路徑 - 一條以此結束,一條以此開始。這意味着一個動作創建兩個新的資源,同時刪除另一個(被分割的路徑)。

因此,如果上述示例中的路徑是系統中的唯一路徑,並且我用一次調用將其拆分,那麼系統現在將包含兩條新路徑,原始路徑將消失。例如:

<Path> 
    <Point>32,32</Point> 
    <Point>32,34</Point> 
</Path> 

<Path> 
    <Point>32,34</Point> 
    <Point>34,34</Point> 
</Path> 

我很苦惱這將如何被處理RESTfully。如何處理導致創建/修改/刪除多個資源並將其傳遞給調用者的調用?

我絕對可以通過多次調用(兩個POST創建新路徑和一個DELETE刪除原來的),但我希望這是一個單一的調用。

回答

1

我會盡力實現它像@Darrel Miller's答案卻讓它少一點RPCish來解決。 這個想法是創建一個PathSplit資源,引導客戶端完成事務的每一步。這樣,客戶就知道每一步的結果,並知道如果出現錯誤,就會退出。

像這樣的東西應該做的伎倆。

POST /pathsplit HTTP/1.1 
Content-Type: application/vnd.acme.pathsplit+xml 
<pathsplit xmlns="http://schema.acme.com"> 
    <path> 
    <id>123</id> 
    </path> 
    <splitpoint> 
     <point>32,34</point> 
    </splitpoint> 
</pathsplit> 

=> 
HTTP/1.1 201 Created 
Content-Type: application/vnd.acme.pathsplit+xml 
Location: 
    http://acme.com/pathsplit/11 

<pathsplit xmlns="http://schema.acme.com"> 
    <path> 
    <id>123</id> 
    </path> 
    <splitpoint> 
     <point>32,34</point> 
    </splitpoint> 
    <newpaths> 
    <Path> 
     <Point>32,32</Point> 
     <Point>32,34</Point> 
    </Path> 
    <Path> 
     <Point>32,34</Point> 
     <Point>34,34</Point> 
    </Path> 
    <createuri>http://acme.org/trips/paths</createuri> 
    </newpaths> 
    <oldpath> 
    <uri>http://acme.org/trips/paths/123</uri> 
    </oldpath> 
    <status>in-progress</status> 
    <pathscreated>0</pathscreated> 
</pathsplit> 

有了這樣的客戶端可以隨時GET的pathsplit資源,看採取何種行動。在這個例子中,它將在createuri鏈接之後創建新的paths並且發送POST請求newpaths中的每個新的path。服務器在創建每個新資源時更新狀態。

一旦狀態爲pathscreated爲2,客戶端可以通過跟隨URI併發送DELETE動詞來刪除舊的path。最後,它會刪除pathsplit資源,從而表明一切都成功了。

在路上的每一步,在一個錯誤的情況下,或在網絡中斷的太常見情況下,客戶總是知道什麼狀態服務器處於什麼狀態的交易是英寸

只要交易尚未完成,路徑資源就會保持可用狀態。 客戶端還可以選擇還原尚未完成的事務。同樣,由於它知道哪些操作已成功完成,哪些沒有完成,因此可以始終退出事務處理。

+0

啊...這是我所尋找的更多。我想我仍然希望它是一個單一的請求,而不是讓客戶端通過執行分割的工作流程(儘管我喜歡你的建議)。我可以看到保留一段時間的路徑資源。客戶端稍後可以刪除它以「撤消」拆分,或者一段時間後,服務器可以刪除拆分路徑資源(刪除撤銷能力)。思考? – SingleShot

+0

掛在過去的資源上會導致你的API用戶混淆。 DELETE謂詞用於刪除資源,預期的操作是僅刪除該資源。在您提出建議的情況下,您不僅會刪除資源,還會刪除和更改其他資源。如果您希望能夠撤消拆分,我會對pathsplit資源執行GET操作,然後使用pathsplit資源作爲有效內容執行POST操作以創建新的undosplit資源。 –

+0

undosplit資源知道如何從pathsplit資源中撤消拆分,並且可以創建並返回新資源。 「撤消拆分」被理解爲刪除兩個資源並創建新資源,等同於原始的「未拆分」,但不是同一個實例。 –

1

簡單的答案是,使這個單一的調用只是不是真的RESTful;除非你重新編碼你的表示,否則我對REST和HATEOAS的理解是這種過程試圖在服務器端表示中插入一個動詞,這是一個很大的禁忌。這並不是說你想做的事情不能以REST方式完成,但我認爲它涉及到對錶示樹的一些重構。

然後有一個「爲什麼」你想這是一個單一的電話的問題;我明白爲什麼從交易的角度來看它是有道理的。這似乎意味着將事務REST表示展示給客戶端,因此客戶端可以正確地管理事務。我並不是說這很簡單,但...

0

一個嚴格的CRUD操作的解決方案在我看來沒有用。但是,資源操作不一定需要是CRUD操作。許多人甚至認爲這是設計REST界面的不好方法(只是谷歌休息+粗俗)。

所以,我認爲當您將一個拆分操作定義爲一個REST調用時,它是完全可以的。當您僅對一個資源(原始路徑)應用此操作時,可以直接在其上定義此操作。無需在多個資源上定義它。

2

這不完全漂亮,但這個可以有「處理資源」

POST /PathSplitter?SplitAt=(32,34) 
Content-Type: application/vnd.acme.path+xml 
<Path> 
    <Point>32,32</Point> 
    <Point>32,34</Point> 
    <Point>34,34</Point> 
</Path> 

=> 
200 OK 
Content-Type: application/vnd.acme.pathlist+xml 
<Paths> 
    <Path href="/trips/1234/paths/4"/> 
    <Path href="/trips/1234/paths/5"/> 
</Path> 
相關問題