在没有主键的情况下更新记录的REST方法是什么?

时间:2019-05-04 17:33:09

标签: rest api post patch put

我创建了一个REST API。根据我的设计,我们必须每天每天存储用户的血糖水平。

问题是:

  • 我要对插入和更新操作使用单个端点
  • 我不想在URI中使用blood-sugar资源的主键,因为我只想在一天之内存储最后一个值

例如,如果我拨打电话

POST https://{host}/users/1/blood-sugar/

{
    "measureDate": "2019-05-04",
    "bloodSugarLevel": 86
}

它将创建一个blood-sugar资源,数据库将分配ID(例如ID=333

直到这里都可以。

然后,我希望能够再次发出相同日期但血糖水平不同的请求。结果,我希望后端应该找到先前的blood-sugar资源(带有ID=333)并更新bloodSugarLevel字段,因为我们已经有了这一天的记录({{1 }})。我不想在请求正文或URI中发送2019-05-04

ID=333

我的问题是:

是否有任何方法可以通过REST实现此(或类似结果)?您可以要求我更改VERB或URI或请求正文。

  

注意:   如果我使用WCF或类似方法执行此操作,则只有一种方法可以满足我的所有要求。例如:POST https://{host}/users/1/blood-sugar/ { "measureDate": "2019-05-04", "bloodSugarLevel": 105 # only this value is different }

谢谢。

1 个答案:

答案 0 :(得分:2)

  

有什么办法可以通过REST达到这个(或类似的)结果?

只需将更新的值发布到相同的端点即可。

考虑如何在万维网上执行此操作。您将访问一个网站,并加载某种形式,其中包含日期的文本字段,bloodSugarLevel的文本字段和提交按钮。这样会将消息发布到Web服务器,您的浏览器将获得一些响应。

请注意,作为客户端,我们真的不在乎服务器是将新消息追加到列表中,还是将消息追加到地图中,还是对RDBMS或图形数据库进行一些巧妙的处理。这些是实施细节;拥有统一接口的部分原因在于该接口意味着客户端(和通用组件)实际上不需要知道发生了什么。

另一个可行的应用程序协议是将bloodSugarLevel视为用户可以在本地编辑的文档。这样,客户端就可以使用任何支持HTTP的编辑器来完成正确的操作。

GET /users/1/blood-sugar/

200 OK

{
    "measureDate": "2019-05-03",
    "bloodSugarLevel": 90
}

PUT /users/1/blood-sugar/
{
    "measureDate": "2019-05-04",
    "bloodSugarLevel": 86
}

204 No Content

PUT /users/1/blood-sugar/
{
    "measureDate": "2019-05-04",
    "bloodSugarLevel": 105
}

当网络不可靠时,使用PUT有一些语义上的优势;因为服务器同意消息处理将完全进行,所以客户端可以通过重复发送来响应超时等待确认。

从语义上讲,PUT的意思是“ upsert”,但基本的实现不必一定是upsert。我们只是承诺客户可以期望的语义。