PUT的REST端点应该是GETable吗?

时间:2016-09-15 00:35:03

标签: rest philips-hue

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

{
    "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基于识别&#34;资源&#34;的URL。因此,如果我可以将数据PUT到资源,我也应该能够从该资源获取数据。我无法在任何地方明确地找到它,但是资源的概念并不意味着它吗?

2 个答案:

答案 0 :(得分: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在身体中有状态信息。

答案 1 :(得分:0)

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

您使用飞利浦API的经验是有道理的 - 更改内容,使用PUT方法获取状态,使用GET。我没有解释为什么GET在试图获得状态时失败了。

你引用的文本(没有引用)似乎暗示如果你设置(PUT)你应该能够阅读(GET)某事物价值的东西的价值。使用类似的URL会很有意义。但它归结为如何实施;只有向下投票才能阻止你从数据库中编写DELETE的GET接口(不要这样做)。

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