如何为机器和人类使用一个REST API?

时间:2012-06-01 15:31:29

标签: rest hateoas

我对使用REST API构建Web服务感兴趣。我一直在阅读关于HATEOAS的内容,许多例子通过将它与人类上网时的做法进行比较来解释这个概念。这让我想到,为什么不以人类和机器都能轻易使用的方式构建REST API?

例如,我有一个小部件的内部模型,这个小部件具有部件号,价格等属性。当机器要求小部件列表时,我可以返回JSON表示。

{
    widgets: [
        {
            id: 1,
            part_number: "FOO123",
            price: 100,
            url: "/widget/1"
        },
        {
            id: 2,
            part_number: "FOO456",
            price: 150,
            url: "/widget/2"
        },
        {
            id: 3,
            part_number: "FOO789",
            price: 200,
            url: "/widget/3"
        },
        ...
    ]
}

当一个人通过他/她的网络浏览器请求相同的列表时,似乎我应该能够采用相同的内部模型并对其应用不同的视图来生成HTML响应。 (当然,我会用其他页面元素装饰HTML响应,比如页眉,页脚等。)

这是一个明智的设计吗?为什么或者为什么不?有没有受欢迎的网站呢?

我看到的最大缺点是用户没有明显的方法来删除资源。在我的用例中,我不会让用户修改或删除资源,所以这不是一个交易破坏者,但一般来说你会如何处理?

4 个答案:

答案 0 :(得分:6)

@mehaase

首先,我建议使用一种已注册的JSON超媒体格式:

所有这些都提供了用于创建具有语义链接关系的链接的显式语义。

例如,使用Collection(.next)+ JSON,您可以像这样表达您的小部件:

{"collection": {
  "version": 1.0,

  "items": [{
    "href": "/widget/1",

    "data": [{
      "name": "id",
      "value": 1,
      "prompt": "ID"
    }, {
      "name": "part_number",
      "value": "FOO123",
      "prompt": "Part number"
    }, {
      "name": "price",
      "value": 100,
      "prompt": "Price"
    }],

    "links": [{
      "rel": "self",
      "href": "http://...",
    }, {
      "rel": "edit",
      "href": "http://..."
    }]

  }]
}}

这为您提供了几个优势:

从示例中可以看出,它有足够的信息可以转换为HTML(或其他格式)。

  

我看到的最大缺点是用户没有明显的方法   删除资源。在我的用例中,我不会让用户   修改或删除资源,所以这不是一个交易破坏者,而是在   一般如何处理?

对于这个读取“编辑”链接关系规范,它意味着可以删除资源。

答案 1 :(得分:4)

你可以做几件事,但第一个前提是现代的“通用”网络浏览器真的很糟糕的REST客户端。

如果您的大多数交互都受到JavaScript的保护和管理,那么如果您编写“富客户端”,那么您可以说更多地依赖于JS生成的请求,而不仅仅是链接,表单和后退按钮,那么它可以成为更好的REST客户端。

如果你坚持使用表单和链接的通用浏览器体验,你可以通过重载POST来绕过缺少其他HTTP动词。你失去了中间人的一些保证。 DELETE是幂等的,POST不是,这有影响,但它不是毁灭性的,你只需要解决它。你可以用POST做幂等事,但中间人不会“知道”他们是,所以他们不能假设它是幂等的。

如果您最终不得不去“POST uber alles”,您将限制您的计算机客户端到同一个api,或者您提供并行服务 - POST愚蠢客户端使用的服务以及具有完整色域的其他服务可供他们使用。

也就是说,如果您选择基于XML的超媒体格式,那么您可以做的是将XSL转换添加到XML有效负载。浏览器将在有效负载上运行XSL,创建一个你喜欢的页面(页眉,页脚,足够的JS来扼杀马等),而机器将忽略它的这一方面,并​​专注于给定的数据。 / p>

在这方面给你一个“两全其美”。

答案 2 :(得分:1)

您始终可以构建REST API,然后围绕它构建自己的,人性化的Web应用程序。这是一种常见的做法,因为您具有开箱即用的功能和可扩展的开发人员系统。

答案 3 :(得分:0)

只需使用带有RDFa的HTML即可。因此人类可以读取HTML并且机器可以读取RDFa注释。你需要像hydra这样的REST词汇来注释链接,以及其他词汇,比如schema.org来注释内容。

为不同类型的客户端使用不同媒体类型的另一种选择,例如人类的HTML和机器的JSON-LD。