REST - Uniform Interface究竟是什么意思?

时间:2014-08-07 00:52:09

标签: rest definition uniform-interface

Wikipedia has:

  

统一界面

     

统一接口约束是任何REST服务设计的基础。[14]统一界面简化和分离了体系结构,使每个部分都能独立发展。该界面的四个指导原则是:

     

资源识别

     

在请求中标识单个资源,例如在基于Web的REST系统中使用URI。资源本身在概念上与返回给客户端的表示分开。例如,服务器可以将数据从其数据库发送为HTML,XML或JSON,其中没有一个是服务器的内部表示,并且它是相同的一个资源。

     

通过这些陈述操纵资源

     

当客户端持有资源的表示形式(包括附加的任何元数据)时,它具有足够的信息来修改或删除资源。

     

自我描述性消息

     

每条消息都包含足够的信息来描述如何处理消息。例如,要调用的解析器可以由Internet媒体类型(以前称为MIME类型)指定。响应还明确指出了它们的可缓存性。

     

超媒体作为应用程序状态的引擎(A.K.A. HATEOAS)

     

客户端仅通过服务器在超媒体内动态识别的动作(例如,通过超文本内的超链接)进行状态转换。除了应用程序的简单固定入口点之外,客户端不会假定任何特定操作可用于除先前从服务器接收的表示中描述的任何特定资源。

我正在听这个主题的讲座,讲师说:

  

“当有人使用我们的API时,如果您能够获得客户对象并且您知道有订单对象,那么您应该能够获得具有与客户对象相同的模式的订单对象。这些URI看起来会像彼此一样。“

这让我觉得错误。这不是关于URI的外观或者是否存在一致性,因为它是使用URI的方式(识别资源,通过操纵资源)表达,自我描述性消息和仇恨)。

我认为这不是统一界面的意思。究竟是什么意思?

4 个答案:

答案 0 :(得分:34)

使用接口将类与其依赖项的实现分离是一个非常古老的概念。我很惊讶你还没听说过......

通过REST,您可以使用相同的概念将客户端与REST服务的实现分离。为了定义这样的接口(客户端和服务之间的契约),您必须使用标准。这是因为如果你想要一个互联网规模的REST服务网络,你必须强制执行全局概念,比如标准,以使它们相互理解。

  • 资源标识 - 您使用URI(IRI)标准来标识资源。在这种情况下,资源是一个Web文档。

  • 通过这些表示操作资源 - 您使用HTTP标准来描述通信。因此,例如GET意味着您要检索有关URI标识资源的数据。您可以使用HTTP方法和URI来描述操作。

  • 自我描述性消息 - 您使用标准MIME类型和(标准)RDF词汇来使消息具有自我描述性。因此,客户端可以通过检查语义来查找数据,并且不必知道服务使用的特定于应用程序的数据结构。

  • 超媒体作为应用程序状态的引擎(A.K.A. HATEOAS) - 您使用超链接和可能的URI模板将客户端与特定于应用程序的URI结构分离。您可以使用语义来注释这些超链接,例如IANA链接关系,因此客户将理解他们的意思。

答案 1 :(得分:3)

你的问题有点宽泛,你似乎要求重述你的定义。您是在寻找示例,还是不了解具体说明的事项。

我同意这一行:

  

这些URI会看起来像彼此

从根本上说是错误的。为了满足Uniform接口约束,URI不需要看起来彼此相似。需要提供的是发现标识资源的URI的统一方法。这种统一的方式对于每种消息类型都是唯一的,并且必须有一些商定的格式。例如,在HTML中,一个文档资源通过一个简单的标记链接到另一个文档:

<a href="URI of related resource" rel="defined relationship">fallback relationship</a>

HTTP服务器将html作为text / html资源类型返回,浏览器具有一致的解析方式。 anchor标记是超媒体控件(HATEOAS),它具有相关资源的唯一标识符。

唯一没有涉及的是操纵。 HTML有另一个很棒的例子,表单标签:

<form action="URI" method="verb">
  <input name=""></input>
</form>

再次,浏览器知道如何解释此元信息以定义在URI上作用的资源的表示。不幸的是,HTML只允许你为动词获取和发布...

更常见的是,在基于JOSN的服务中,当您检索Person资源时,它很容易操纵该表示,然后将其PUT或PATCH直接返回到它的规范URL。修改它不需要预先存在的资源知识。现在,当我们编写客户端代码时,我们得到的结论是,我们实际上需要在使用之前知道形状......但这实际上只是为了使我们的解析器高效且简单。我们可以使解析器分析资源的每个部分的语义含义,并通过解释修改的意图来修改它。 IE:命令让10岁以上的人解析查找年龄的资源,确定年龄,然后将该值添加10年,然后将该资源发送回服务器。是否更容易使代码期望年龄为$ .age的JSON路径?绝对......但并非特别必要。

答案 2 :(得分:3)

“统一接口”实际上意味着服务器响应应该宣布可用的操作和资源。换句话说,查询资源应该允许客户端在不事先知道的情况下请求其他操作和资源。

JSON-API规范提供了一个很好的例子:

{
  "links": {
    "self": "http://example.com/articles",
    "next": "http://example.com/articles?page[offset]=2",
    "last": "http://example.com/articles?page[offset]=10"
  },
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!"
    },
    "relationships": {
      "author": {
        "links": {
          "self": "http://example.com/articles/1/relationships/author",
          "related": "http://example.com/articles/1/author"
        },
      },
      "comments": {
        "links": {
          "self": "http://example.com/articles/1/relationships/comments",
          "related": "http://example.com/articles/1/comments"
        }
      }
    },
    "links": {
      "self": "http://example.com/articles/1"
    }
  }]
}

通过分析这个单一的回应,客户知道:

  1. 他在查询什么(文章)
  2. 结构化文章(id,标题,作者,评论)如何
  3. 如何检索相关对象(即作者,评论列表)
  4. 有更多文章(10,基于当前的回复长度和分页链接)
  5. 我希望这会有所帮助 对于那些对这个主题充满热情的人,我强烈建议您阅读Thomas Fielding's dissertation

答案 3 :(得分:2)

好的,我想我明白这意味着什么。

来自Fieldings论文:

  

将REST架构风格与其他基于网络的样式区分开来的核心功能是强调组件之间的统一接口(图5-6)。通过将通用性的软件工程原理应用于组件接口,简化了整个系统架构,提高了交互的可见性。

他说组件之间的接口必须相同。 IE浏览器。客户端和服务器之间以及任何中间人,所有这些都是组件。