【问题标题】:Should a REST endpoint for PUT be GETable?PUT 的 REST 端点应该是 GETable 吗?
【发布时间】:2016-09-15 00:35:02
【问题描述】:

我开始学习 REST(针对我自己的项目),同时尝试使用 Philips Hue API。我发现了一个奇怪的 IMO 效应:要打开灯,我需要 PUT {"on": true}/api/<KEY>/lights/6/state。可以在/api/<KEY>/lights/6/ 上使用GET 检索灯光状态,我会收到例如

{
    "state": {
        "on": true,
        "bri": 113,
        "alert": "none",
        "reachable": true
    },
    "type": "Dimmable light",
    "name": "Light 6",
    "modelid": "LWB006",
    "manufacturername": "Philips",
    "uniqueid": "00:17:89:01:11:57:da:8d-0b",
    "swversion": "5.38.1.15095"
}

但是我不能GET 来自/api/<KEY>/lights/6/state 的任何东西:

[
    {
        "error": {
            "type": 3,
            "address": "/lights/6/state",
            "description": "resource, /lights/6/state, not available"
        }
    }
]

我不确定我是否真的在任何地方读过它,但我从阅读许多关于 REST 的不同文本中得到的感觉告诉我,如果我可以PUT/api/endpoint,我应该也可以GET 它背部。因此,如果我设计了 API,它将是 PUT {"state": {"on": true}} /lights/6GET /lights/6/state 将返回 {"on": true}

对此有什么普遍共识吗?

更新:正如正确地提到的,我实际上并没有引用任何东西。现在尝试查找参考资料,我设法找到了a popular tutorial,这对我来说似乎开始完全错误:

PUT - 用于创建新资源。
POST - 用于更新现有资源或创建新资源。

我相信所有其他资源,例如thisthis,很清楚不应该使用 POST 来更新。

但总的来说,REST 是基于标识“资源”的 URL。因此,如果我可以将数据放入资源中,我也应该能够从该资源中获取数据。我在任何地方都找不到明确写的,但是资源的概念是否暗示了它?

【问题讨论】:

  • 是的,你错了。我建议阅读 REST 的基础知识。只有在服务端将 GET 声明为 GET 并且与其他方法相同 - PUT 、POST 、 DELETE .. GET 才会给您结果
  • @Rohit,你真的很快 :) 你能把你的评论转换成答案吗?

标签: rest philips-hue


【解决方案1】:

我想我对 Phillips Hue 的方式有点厌烦。我的理解一直是您正在使用位置的资源。 POST 应该创建一个指定类型的新资源,PUT 应该更新它指向的资源(或者如果它不存在,则在给定位置创建一个)等等。

如果它是POST .../lights/:id/states,我觉得这可能更传统,它为给定的光创建了一个新的state 资源,也许描述了它的当前状态。这也具有(传统上)优势,这意味着该设备有状态历史。 (例如,GET .../lights/6/states/3 也会存在)

PUT 方法请求将封闭的实体存储在提供的 Request-URI 下。如果 Request-URI 引用一个已经存在的资源,封闭的实体应该被认为是在源服务器上的一个修改版本。 https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

如果状态只是光的一个属性,而不是被视为它自己的资源,我希望行为如您所描述的那样:PUT .../lights/6 在正文中带有状态信息。

【讨论】:

  • 嗨,戴夫,我不知道我是否同意您的观点(是声明新资源还是现有资源的属性?),但最后一句话很清楚 :) 我的问题是关于无法得到我可以放的东西。
【解决方案2】:

我们在工作中讨论过这个问题。以我的经验,在Get/Post/Delete/等的早期,只使用了GET和POST; POST 用于发送大量数据或从 URL 中“隐藏”的数据。其他 HTTP 方法基本上是作为使用 GET/POST 作为“载体”的子协议实现的。这是可能的,因为 REST 服务在收到请求后可以做任何它想做的事情。随着网络服务变得更加规范,各种 HTTP 方法开始得到适当使用。

您对飞利浦 API 的体验很有意义 - 要更改某些内容,您使用 PUT 方法,要获取状态,您使用 GET。我无法解释为什么 GET 在尝试获取状态时失败。

您引用的文本(没有引用)似乎暗示如果您设置(PUT)某事物的值,您应该能够读取(GET)该事物的值。使用类似的 URL 会很有意义。但这归结为它是如何实施的。没有什么比反对更能阻止你编写一个从数据库中删除的 GET 接口(不要这样做)。

当您编写 REST API 时,我强烈建议您遵循当前的最佳实践,使用已定义并适合您的应用程序的 HTTP 方法。它将使 API 变得直观,并且您的后端代码将模块化且易于维护。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-05
    • 2014-08-06
    • 2011-10-24
    • 2014-11-06
    • 2017-10-08
    • 2020-02-14
    • 2019-11-05
    • 2019-12-24
    相关资源
    最近更新 更多