我正在尝试构建一个 RESTful Web 应用程序,其中使用 GET、POST、PUT 和 DELETE。但我对这个特定应用程序中 DELETE 的使用有疑问。
首先介绍一下背景:
我的 web 应用程序管理通用实体,这些实体也在另一个系统中进行管理(而且,它总是创建)。因此,在我的网络应用程序中,每个实体都将使用唯一的密钥存储在数据库中。但我们通过 URL 访问它们的方式是使用 other 系统的唯一密钥。
我想,一个简单的例子就能清楚地说明这一点。获取网址
/entity/1
。这将显示其他系统中 ID 为 1 的实体的信息,而不是我自己的系统。事实上,我系统中的 ID 将被完全隐藏。在我自己的系统中,不会有用于访问 ID 为 1
的实体的 URL 方案。好吧,现在我们知道了我的 web 应用程序的结构,让我们返回删除这些实体。
我的系统中会有一种“删除”实体的方法,但我在它周围加上了引号,因为它实际上不会从数据库中删除它们。相反,它会用一个属性来标记它们,以防止它在您转到
/entity/1
时出现。
因此,我觉得我应该使用
PUT
(这样“删除”将是幂等的),因为我从数据的角度来看,只是简单地设置一个属性。
所以,问题是:RESTful 方法是否对数据保真度(在这种情况下,很明显我是
PUT
ing),或者应用程序中数据的表示(在这种情况下,我似乎是
) DELETE
ing)?DELETE
。
您打算对数据执行的操作称为“软删除”:您设置一个标记并避免出现标记的项目。这是您的网络应用程序内部的,用户不必知道您是软删除而不是删除或您想要执行的任何操作。这就是为什么您应该使用
DELETE
动词。
DELETE
动词似乎是正确的方法
一切都好像该项目要一劳永逸地删除,但工程师希望将其保留在数据库中的某个位置
POST
)上使用
/resource/:id/softdelete
,而销毁操作将是使用 DELETE
的操作。 另一种方法可能是使用不带查询参数的DELETE
来软删除,并添加
?destroy=true
来实际销毁。但这种方法似乎不太明确并且更容易出错。
来源:Mark Massé 的 Rest-API 设计规则书
建议:
POST: /entity/1/your-soft-delete-controller-name
,您正在执行删除,因为 URL /entity/1
在删除后将不再可用。软删除或硬删除数据库中的某些内容这一事实并不重要。
它表达的是对源服务器的URI映射的删除操作,而不是期望删除先前关联的信息。如果目标资源有一个或多个当前表示,
它们 可能会也可能不会被源服务器破坏,并且 关联的存储可能会也可能不会被回收,这完全取决于 关于资源的性质及其来源的实施 服务器(超出了本规范的范围)。