2012-02-27 35 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