超媒体API链接遍历&实际性

时间:2013-08-07 21:58:58

标签: api rest service hypermedia

我一直在尝试构建基于超媒体的API。事情似乎运作良好。当我拿到/books/isbn/12313441213时,我会得到类似的结果:

<book>
  <id>123</id>
  <name>Hypermedia APIs</name>
  <description>Basic api design techniques</description>
  <tags>
    <tag>rest</tag>
    <tag>api</tag>
    <tag>service</tag>
  </tags>
  <authors>
    <link rel="author" uri="/authors/id/22" />
    <link rel="author" uri="/authors/id/18" />
  </authors>
</book>

现在我可以从这个资源中遍历作者了。当我获取/books/by/author/id/18时,我会得到类似的内容:

<books>
  <book id="123">
    <name>Hypermedia APIs</name>
    <link rel="self" uri="/books/id/123" />
  </book>
  <book id="191">
    <name>Chef Recipes for Rails Developers</name>
    <link rel="self" uri="/books/id/191" />
  </book>
  <book id="220">
    <name>Rails 4 Cookbook</name>
    <link rel="self" uri="/books/id/220" />
  </book>
  <book id="292">
    <name>Ruby 102</name>
    <link rel="self" uri="/books/id/292" />
  </book>
  <book id="432">
    <name>Semantic Architecture</name>
    <link rel="self" uri="/books/id/432" />
  </book>
  <book id="501">
    <name>Service Oriented Design</name>
    <link rel="self" uri="/books/id/501" />
  </book>
</books>

这对我来说似乎也很好。无论这种uri模板的方式是否良好,我的问题是如何实际遍历这样的链接?

考虑到您需要全面深入的资源(包括作者详细信息),您必须至少对服务器进行3次调用。再次对于集合,您必须对服务器进行大量调用。是的,也许我可以在这里利用资源扩展,但是为什么我会使用超媒体链接,因为我的所有客户都将及时使用扩展资源。

我知道我们通过让客户端遍历链接获得了很多收益(即,如果客户端构建基于关系的资源发现,当我们更改api时,它们将受到最小影响,或者他们被迫从资源中获取最新的模式端点本身等)。然后,这种方法的实用性,或者这种方法的表现会破坏系统。

要么我没有在超媒体api设计中获得某些东西,要么超媒体api听起来不错,但它似乎只是一个理论上的想法,而不是一个实际的想法。

对此有何想法?

2 个答案:

答案 0 :(得分:2)

这是一个很好的问题。事实上,另一个重要问题是:谁知道遍历可以达到特定资源R?

例如,要访问“book-detail”资源,客户必须拨打api的条目,例如“/”,然后使用rel“book-categories”获取uri到book-categories然后拨打电话到OPTIONS看看是否可以在该资源上进行GET操作,然后获取图书类别,然后获取rel到“书籍类别”资源......等最终转到“书籍细节”资源。通往资源R的遍历路径应该是客户知识的一部分。但是不要对网址进行硬编码,只需在运行时阅读网址即可。这是考虑机器到人的情况。 效率低下仍然存在。 对于机器到机器的情况,从“/”开始的自动机可以通过您的API并对您的资源进行某些处理。如果自动机必须到达树中的所有资源(或者可能是状态机),那么就没有低效率。但是如果自动机需要在树中调用资源,并且它只知道API的入口点,那么它将运行到几次调用以达到它的问题。

许多人会告诉你使用etags和/或memcached来引入缓存,但缓存是为了增强性能,你不能100%依赖缓存,因为缓存变得陈旧,所以在那些情况下,遍历资源R1到Rn的代码应该在你的客户。

检查我的问题:https://stackoverflow.com/questions/15214526/why-hypermedia-api

但是要回答你关于实用性的问题:如果你有一个业务工作流程,其中客户端需要转到资源R1然后R2然后...... Rn并且你想强制执行该流程,超媒体是实用的。我假设没有直接调用Resource Rx而不通过R1 - &gt; R2 - > ... Rx-1。

答案 1 :(得分:1)

使用参数会更传统:

GET / books?author = 18

我希望回应看起来更像:

       超媒体API             

您还可以使用参数指示要显示的子资源上的哪些字段。像

这样的东西

GET / books / 18?expand = author(姓名,生日)

将返回作者的姓名和生日,作为响应中作者标记的一部分。然后,您可以提供合理的默认值,以确定用户在索要书籍时获得的作者信息量(可能只是作者的自己和姓名),但如果他们想要通过更改参数,他们可以获得更多详细信息。

这些类型的自定义可以帮助减少需要调用的次数。

另一个观察结果是,可以在客户端或中间代理上缓存大量此类数据。关于书籍或作者的可能性不大,因此这些资源可以让客户端长时间缓存它们。然后根本没有往返 - 客户端点击他们自己的本地缓存来获取数据。