2012-02-27 23 views
4

我正在爲RESTful API設計自定義媒體類型,並研究了一些「標準」鏈接關係的類型和語義含義,以便爲我的設計提供一些指導。鏈接關係粒度與自定義媒體類型中的精度?

爲了演示這個問題,假設我有一個資源,可以執行標準讀取,更改,刪除方法,並且分別使用GET,PUT和DELETE的HTTP成語來實現這些方法。

我可以合理地(重新)用作RFC5023定義的「編輯」鏈接關係(從IANA link registry),它規定:

」 ...的價值‘編輯’指定的值href屬性 是可編輯成員條目的IRI。當出現在 atom:條目中時,href IRI可用於檢索,更新和刪除由該條目表示的資源....「

這樣,用戶代理可以理解具有「編輯」關係的鏈接將允許資源爲GET,PUT和DELETEd。

但是,這裏存在的問題是,如果編輯資源狀態以使資源現在僅支持GET和DELETE操作,則「編輯」關係不再精確。選項A:指定另一個(複合)鏈接關係,該鏈接關係僅支持GET & DELETE,或者ii)選項B:爲每個可能的狀態轉移指定單獨的鏈接,並使用適當的表示允許的狀態轉移。後一種方法提供精確度,但似乎過於冗長。 (選項C)我可以保留「編輯」關係並接受缺乏精確性,即鏈接將傳遞GET,PUT,DELETE語義,但會嘗試使用PUT的用戶代理HTTP錯誤「405 - 方法不允許」。但是,我對這種方法並不滿意,因爲它暗示客戶端不支持狀態轉換。

總之,問題是什麼纔是平衡鏈接關係普遍性和精度的最明智的方法?

+2

交叉發佈到API Craft [鏈接](http://groups.google.com/group/api-craft/browse_thread/thread/5d478b216f5e0322) – 2012-02-27 21:37:06

回答

2

經過一番認真的調查我的結論是我試圖解決錯誤的問題。在鏈接關係的定義中,並非關注HTTP動詞的粒度,更精確的問題是「HTTP成語(動詞)是否應該混合到鏈接關係中?」。

我曾經使用AtomPub作爲如何做鏈接關係(對於REST)的參考,事實證明這是一個錯誤。在Roy Fielding的AtomPub mail archive中建議(以REST術語來說)「編輯」的方法是錯誤的,並得出結論認爲這是不必要的。這個論點表明,還有其他(HTTP)機制可以傳達這樣的屬性,因此它們在'rel'屬性中沒有地位。

其他機制沒有取得在郵件歸檔明確的,但我懷疑他們包括下列選項:

  1. 讓用戶代理嘗試並檢查響應(2XX或4XX),或
  2. 使用OPTIONS向資源請求允許的操作,或者
  3. 在成功的GET請求中包含「允許」頭,以將允許的資源操作傳送給用戶代理。

有趣的是,羅伊認爲'Allow' header是「超文本的一種形式」。

總之,回答我的問題是:

不要混爲一談HTTP操作成 '相對'」 的意思

使用(提供的)HTTP機制來確定允許的資源操作

編輯:我應該補充說的是,POST有一些特殊用途作爲數據接收器,這些規則需要稍微彎曲一下,但這是一種特殊情況。

0

另一種選擇是離開「編輯」關係,並允許消費者想知道他們當前可以在資源上執行哪些操作,以使用OPTIONS HTTP方法發出請求,並且服務器可以返回帶有Allow標題指示資源上允許的方法,因爲它是當前狀態。

沒有額外的請求,它不會提供PUT操作的可用性,但它相當「乾淨」,並且允許使用標準關係和HTTP機制。

+0

皮特,感謝您的支持。雖然HTTP OPTIONS方法提供了一種實用且標準的發現方法,但我認爲它有損於鏈接href的語義意義應由rel傳達的事實。如果不是,那麼rel屬性的「含義」就會被稀釋。我欣賞'rel'屬性的確切含義,或者實際上OPTIONS的響應返回資源方法的時間點視圖 - 這可能會改變。如果資源發生變化,405可能會繼續。然而,我的重點是在這些不同情況下定義rel的含義。 – paulkmoore 2012-02-28 11:32:46

+0

夠公平的。我在API-Craft清單上也是如此,因爲我很好奇別人也有什麼要說的。 – Pete 2012-02-28 13:08:20

+0

皮特,經過很多調查工作,我認爲我現在對問題有了合理的理解。 '使用OPTIONS'的答案是解決方案的一部分 - 請參閱我自己的答案中的ramblings。 – paulkmoore 2012-05-15 20:12:24

1

WRML規範採取了一種方法,其中每個「鏈接」對象可以具有rel屬性。然後

GET /dogs/1 
{ 
    "links" : { 
     "self" : { 
      "href" : "http://api.example.com/dogs/1 
      "rel" : "http://api.example.com/relations/self" 
     } 
    } 
} 

而且客戶可以按照相對URL

GET /relations/self 
{ 
    "name" : "self" 
    "description" : " A reference back to the same object you are currently interacting with" 
    "method" : "GET" 
} 

該規範並不建議每個相對應指定1點完全相同的方法。這有利於與客戶非常明確地說明他們應該做什麼,並且限制了所需的帶外知識的數量。我個人在這個問題上來回回顧,因爲我認爲某些「rel」提供多種HTTP方法是有一定價值的。想象一下,一個鏈接,狗

GET /dogs/1 
{ 
    "links" : { 
     "self" : { 
      "href" : "http://api.example.com/dogs/1 
      "rel" : "http://api.example.com/relations/self" 
     } 
     "owner" : { 
      "href" : "http://api.example.com/owner/1 
      "rel" : "http://api.example.com/relations/owner" 
     } 
    } 
} 

的主人這將是很好,讓「老闆」意味着GET和PUT,因爲這些都是有效的行動。與此相反的是,在進行更新之前,您應該始終需要執行GET操作,以便在檢索資源之前提供該信息的價值是不良形式。

所以我想所有的說我會投票給OPTION B.

+0

丹尼爾 - 有趣的是得到它的WRML視圖 - 謝謝。作爲比較的一點,[RFC5988](http://tools.ietf.org/html/rfc5988)允許在同一鏈接中存在多個關係,比如rel =「self edit」,這會減少冗長度,並允許你提到的多重性。 RFC還指出「客戶端不應該自動訪問」rel URI,但這主要是服務器負載問題。給定一個合適的緩存策略,我會認爲這是一個合理的方法。 – paulkmoore 2012-02-28 16:51:43