使用 DELETE 或 PUT 删除数据库中的外键?

Using DELETE or PUT to delete a foreign key in a database?

我们目前正在创建一个模仿 flickr 作为一个项目如何工作的网络应用程序。

在这个应用程序中,我们有画廊和照片。

在每个图库中,我们将照片 ID 存储在一个数组中。

gallery.photos = [ photoId1, photoId2, photoId3 ]

如果我们想从图库中删除照片,但是照片保留在数据库中,如果您转到用户的个人资料而不是从图库中可以访问。

所以如果我们 DELETE url/gallery/photos/photoId3 然后 GET url/gallery/photos/photoId3,它会 return 一个 Error 404

目前关于我们应该使用 DELETE 还是 PUT 存在争论。

有人说 DELETE 因为我们正在删除内容并且无法从中访问照片 url。

其他人说 PUT 因为我们只是在编辑照片 ID 列表。

那么,我的问题是,对于这个问题是否有共同的约定?

is there a common convention when it comes to this problem ?

要认识到的重要一点是 DELETE 和 PUT 属于 transfer of documents over a network 域。

我们以标准方式使用标准方法,以便通用组件可以理解消息的含义并执行智能操作。

如果请求的语义 是“目标 uri 应使用 404 响应 GET 请求”,则 DELETE 是合适的。您的实现如何实现这一点的基本细节无关紧要。

请注意,DELETE 的定义非常明确地说明了语义的限制

If the target resource has one or more current representations, they might or might not be destroyed by the origin server, and the associated storage might or might not be reclaimed, depending entirely on the nature of the resource and its implementation by the origin server (which are beyond the scope of this specification).


事情变得非常混乱的地方:HTTP 让我们就消息语义的含义达成一致,但不限制实现。特别是,删除一个资源也会更改其他资源的表示,反之亦然。

想象一下,如果你愿意的话,图库是一个网页 (/gallery/1/photos/webpage.html),其中 link 用于图像,包括 link 用于/gallery/1/photos/3.

DELETE  /gallery/1/photos/3

这会删除 URI 和图像数据之间的关联,但不会(必然)更改网页,因此您会得到一个损坏的 link。

PUT /gallery/1/photos/webpage.html

这将 link 从网页中取出,但当然仍然可以通过其 URI 直接访问图像。

(注意:如果您的个人资料使用与图库相同的图片 URI,那么这更有可能是您要使用的模型。我们从该网页中取出 link ,但不超出 profile.html。DELETE 会为图片 link 的所有网页生成 404。

如果你想要两者 - 当删除发生时,网页应该自动更新,反之亦然 - 你可以在你的实现中做到这一点(允许副作用) .但是......通用组件不一定知道这两件事都发生了。例如,通用缓存不会知道当您删除图像时网页已更改。而且它不会知道你在编辑网页时删除了图片。

也就是说,我们没有一种标准方法可以在 HTTP 响应元数据中包含描述已被请求更改的 其他 资源。

当然,您可以在响应中包含该信息,以便 bespoke 组件可以执行智能操作。

DELETE /gallery/1/photos/photoId3

200 OK
Content-Type: text/plain

Deleted: /gallery/1/photos/photoId3
Changed: /gallery/1/photos/webpage.html

GET /gallery/galleryId/photos/photoId3 would return an Error 404 as photo isn't in that gallery, however GET /photos/photoId3 would still return the photo assuming you have the correct permissions

好消息:通用组件不知道 /gallery/galleryId/photos/photoId3/photos/photoId3 之间有任何关系。同样,他们在幕后共享信息这一事实是隐藏在 HTTP 外观背后的实现细节。