属性更新的不稳定业务逻辑



我正在构建一个REST API,并试图使其尽可能保持RESTful,但有些事情对我来说仍然不太清楚。我看到了很多关于类似问题的主题,但都集中在更新数据的"简单"问题上,我的问题更多地是关于这方面的业务逻辑。

我的主要问题是由模型的部分更新触发的业务逻辑。我在网上看到很多关于PATCH方法、创建新的子资源或添加操作的不同意见,但这似乎与保持URI简单和结构化的REST方法背道而驰。

我有一些记录需要继续(拒绝、验证、部分验证等),每次更改都会触发额外的操作。

  • 如果被拒绝,应发送一封包含原因的电子邮件
  • 如果已部分验证,则会发送用于完成缺失数据的链接
  • 如果经过验证,则必须创建一些其他资源

可以对状态进行一些其他更改,但这对于示例来说已经足够了。

什么是RESTful方式

我的第一个想法是创建行动:

  • POST /record/:id/refuse
  • POST /record/:id/validate。。等等

对我来说,这似乎很RESTful,但太复杂了,而且,这种方法意味着让多个路由执行基本上相同的事情:更新记录对象中的一个字段

我也看到了PATCH方法的可能性,比如:

  • PATCH /record/:id,其中我检查要更新的字段是否为状态,并检查新值以了解要执行的操作

但当我需要对记录的其他属性执行类似操作时,我觉得它可能会变得过于复杂。

我的最后一个选择,我认为可能是最好的,但我不确定它是否是RESTful,是使用sub-resource状态并使用PUT更新它:

  • PUT /record/:id/status,并打开新值

无论以前的值是什么,切换到接受总是会触发创建,切换到拒绝总是会触发电子邮件。。。etc

这些实现RESTful的方式和哪一种更有意义?还有其他我没有想过的选择吗?

感谢

什么是RESTful方式?

在HTTP中,您的"统一接口"是文档存储的接口。您的Rest API是一个门面,它接受具有远程创作语义(PUT/POST/PATCH)的消息,并且您的实现产生有用的工作作为其处理这些消息的副作用。

参见Jim Webber 2011。

我有一些记录需要继续(拒绝、验证、部分验证等),每次更改都会触发额外的操作。

所以想想我们如何在网络上做到这一点。我们GET一些资源,返回的是记录信息的html表示和描述我们可以执行的操作的一堆表单。因此,有一个被拒绝的表单和一个经过验证的表单,等等。用户在浏览器中选择要使用的正确表单,填写任何补充信息,然后提交表单。浏览器使用html表单处理规则,将表单信息转换为HTTP请求。

对于不安全的操作,表单被配置为使用POST,因此浏览器知道表单数据应该是请求消息体的一部分。

请求的目标uri就是用作表单操作的任何内容——也就是说,表单的表示包括描述表单应该提交到哪里的信息。

就浏览器和用户而言,目标uri可以是任何东西。因此,您可以有单独的资源来处理验证消息和拒绝消息等等

缓存是REST和HTTP中的一个重要思想;HTTP中有特定的缓存无效规则。因此,通常情况下,如果命令成功,您会希望使用一个目标uri来标识您希望客户端重新加载的文档。

所以它可能是这样的:我们GET /record/123,这给了我们很多信息,还有一些表格描述了我们如何更改记录。因此,填写一份,成功提交,现在我们希望表格消失,或者有一套新的表格可用。因此,我们希望重新加载的是记录文档本身,表单的目标uri应该是/record/123

(因此,API实现将负责查看HTTP请求,并弄清楚消息的含义。它们可能都指向一个/record/:idPOST处理程序,该代码将查看message-body,以确定应该由哪个内部函数来完成工作)。

PUT/PATCH是相同的想法,只是我们不提交表单,而是发送资源本身的编辑表示。我们GET /record/123,更改状态(例如,为Rejected),然后将记录的新表示形式的副本发送到服务器进行处理。因此,服务器有责任检查其对资源的表示与新提供的副本之间的差异,并根据这些差异计算任何必要的副作用。

我的最后一个选择,我认为可能是最好的,但我不确定它是否是RESTful,是使用子资源状态并使用PUT更新它

这很好——想想你见过的任何网页,其中的源代码都有指向图像的链接,或者指向java脚本的链接。结果是两个资源而不是一个,每个资源都有单独的缓存条目——当您希望对资源的缓存进行细粒度控制时,这非常好。

但有一个交易——你还需要获取更多的资源。(服务器推送可以缓解部分问题)。

让服务器上的事情变得更容易可能会让客户端上的事情更难——你真的在努力寻找具有最佳平衡的设计。

最新更新