这是一个很好的问题,但我怀疑它最终可能会被标记为固执己见,因为我没有看到正确的答案……正如 OP 所说。
如果这对您的系统有意义,我建议将存档视为单独的对象存储(或者甚至是不同的对象类型)。对象设计不应依赖于数据库如何持久化您的数据。
因此,这是我现在能想到的最 RESTful设计(假设归档和更新始终是独立的操作——它们应该是):
典型(每个人都知道):
GET /api/object get all current objects
POST /api/object new current object
PUT /api/object/id update current object
DELETE /api/object/id delete current object
GET /api/object/id get current object
诡异之处:
POST /api/object/id/archive move object to archive (makes some REST sense)
POST /api/object/id move object from archive (muddy)
档案:
GET /api/object/archive get all archive objects
PUT /api/object/id/archive update archive object (if possible)
DELETE /api/object/id/archive delete archive object (tempting for unarchive)
GET /api/object/id/archive get archive object
或者,也许是存档 URL 的这些 mod 之一:
GET /api/object/archive/id get archive object
GET /api/objectarchive/id get archive object
但......
对于将对象移入和移出存档,上述内容感觉非常混乱(不是非常自我记录)。它还导致一些 REST API 设计痛苦,其中更新/删除/获取存档对象可能不需要特定于存档的功能。因此,我最终确定了这一点:
GET /api/object get all objects
GET /api/object?archived=false get all current objects
GET /api/object?archived=true get all archive objects
POST /api/object new current object, returns all current objects*
PUT /api/object/id update object (current or archived; cannot change archive state)
DELETE /api/object/id delete object (current or archived), returns objects of same archive state as deleted*
GET /api/object/id get object (current or archived)*
PUT /api/object/id/archive body:{archived:true} move object to archive, returns all current objects*
PUT /api/object/id/archive body:{archived:false} move object from archive, returns all archive objects*
* Return could be expanded/overridden with a query string if design calls for it.
诚然,这与我之前将存档视为单独的对象存储的说法大相径庭。然而,这种思考过程最终导致了这种设计妥协。在大多数方面,这对我来说感觉很好。
我个人不同意将查询字符串用于……呃……查询。所以,我没有。数据更改的有效负载——无论多么小——都应该进入正文(即当它不适合 REST 动词和 URL 时)。