Api 自定义媒体类型中的链接关系粒度与精度?

Api 自定义媒体类型中的链接关系粒度与精度?,api,rest,hateoas,hypermedia,Api,Rest,Hateoas,Hypermedia,我正在为RESTful API设计一个自定义媒体类型,并研究了一些“标准”链接关系的类型和语义含义,以便为我的设计提供一些指导 为了演示这个问题,假设我有一个资源,可以对其执行标准的read、change、delete方法,并分别使用GET、PUT和delete等HTTP习惯用法来实现这些方法 我可以合理地(重新)使用“编辑”链接关系(来自),定义如下: “…编辑”的值指定href属性的值 是可编辑成员条目的IRI。当出现在 atom:entry,href IRI可用于检索、更新和删除 由该条目

我正在为RESTful API设计一个自定义媒体类型,并研究了一些“标准”链接关系的类型和语义含义,以便为我的设计提供一些指导

为了演示这个问题,假设我有一个资源,可以对其执行标准的read、change、delete方法,并分别使用GET、PUT和delete等HTTP习惯用法来实现这些方法

我可以合理地(重新)使用“编辑”链接关系(来自),定义如下:

“…编辑”的值指定href属性的值 是可编辑成员条目的IRI。当出现在 atom:entry,href IRI可用于检索、更新和删除 由该条目表示的资源……”

通过这种方式,用户代理可以理解具有“编辑”关系的链接将允许获取、放置和删除资源

然而,问题就在这里,如果对资源状态进行编辑,使得资源现在只支持GET和DELETE操作,“编辑”关系不再精确

为了保持精度,我需要I)选项A:指定另一个(化合物)仅支持GET和DELETE的链接关系,或ii)选项B:为每个可能的状态传输指定单个链接,并使用适当的链接指示允许的状态传输。后一种方法提供了精确性,但似乎过于冗长

或者,(选项C)我可以离开“编辑“关系处于适当位置,并接受缺乏精确性,即链接将传达GET、PUT、DELETE语义,但尝试PUT的用户代理将遇到HTTP错误‘405-不允许使用方法’。然而,我对这种方法也不满意,因为它对客户端意味着一种不受支持的状态转换


总之,问题是平衡链接关系通用性和精确性的最明智的方法是什么?

另一种选择是保留“编辑”关系,并允许希望知道当前可以对资源执行哪些操作的使用者使用OPTIONS HTTP方法发出请求,并且服务器可以返回一个带有标头的响应,以指示给定资源当前状态的资源上允许的方法

它不会在没有额外请求的情况下为您提供PUT操作的可用性,但它相当“干净”,并允许您使用标准关系和HTTP机制。

该规范采用了一种方法,其中每个“链接”对象都可以具有rel属性

GET /dogs/1
{
    "links" : {
        "self" : {
            "href" : "http://api.example.com/dogs/1
            "rel" : "http://api.example.com/relations/self"
        }
    }
}
然后,客户端可以跟踪rel url

GET /relations/self
{
   "name" : "self"
   "description" : " A reference back to the same object you are currently interacting with" 
   "method" : "GET"
}
该规范确实建议每个rel应该指定一种方法。这样做的好处是非常明确地告诉客户他们应该做什么,并限制了所需的带外知识的数量。我个人对此进行了反复讨论,因为我认为说某些“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,因此在检索资源之前提供该信息的值是错误的


所以我猜所有这些都表明我会投票支持选项B。

经过认真的调查,我得出结论,我试图解决错误的问题。与其关注链接关系定义中HTTP动词的粒度,不如更精确的问题是“是否应该将HTTP习惯用法(动词)合并到链接关系中?”

我使用AtomPub作为如何建立链接关系(REST)的参考,结果发现这是一个错误。在这篇文章中,罗伊·菲尔丁(Roy Fielding)建议(在REST术语中)“编辑”的方法是错误的,并得出结论认为这是不必要的。该论点表明存在其他(HTTP)机制来传递此类属性,因此它们在“rel”属性中没有位置

其他机制在邮件存档中没有明确说明,但我怀疑它们包括以下选项:

  • 让用户代理尝试并检查响应(2xx或4xx),或
  • 使用选项向资源询问允许的操作,或
  • 在要传递的成功GET请求中包含“允许”标头 允许对用户代理执行的资源操作
  • 有趣的是,罗伊认为这是“超文本的一种形式”

    总而言之,我自己的问题的答案是:

    “不要将HTTP操作与‘rel’的含义混为一谈”

    “使用(提供的)HTTP机制确定允许的资源操作”


    编辑:我应该补充一点,POST作为数据接收器有一些特殊用途,这些规则需要稍微弯曲,但它们是一种特殊情况。

    交叉发布到API Craft Pete,谢谢。虽然HTTP选项方法提供了一种实用和标准的发现方法,但我认为它有损于链接href的语义应该由rel传达的事实。如果不是,则rel属性的“含义”被稀释。我理解“rel”属性的确切含义,或者实际上,来自OPTIONS的响应返回资源方法的时间点视图,这可能会改变。如果资源已更改,则405可以从任何一个继续。然而,我的重点是在这些不同的场景中定义rel的含义。这很公平。我也在关注API工艺列表,因为我很好奇其他人也会说些什么。皮特,在做了大量调查之后,我认为我现在对这个问题有了合理的理解。您对“使用选项”的回答是解决方案的一部分-请参阅我自己的回答中的漫无边际的部分。感谢您对您进一步研究的结论所作的全面跟进!Daniel-获得WRML视图很有趣-谢谢。作为重点