具有二进制状态的资源的RESTful设计

具有二进制状态的资源的RESTful设计,rest,Rest,我有一个资源,它本质上是一个简单的CRUD文档,它有一个小小的转折点,它可以“切换”到“同步”状态,在这种状态下,它不再使用自己的当前值,而是返回它现在与之同步的“父”文档的值 我正试图找到一种RESTful的建模方法。该资源有一个属性指示此状态synchronized=true/false,还有一个ParentId属性指示它与哪个资源同步 一种选择是只允许在PUT更新过程中更改此项,但这感觉有点不正确,因为这不是文档的一部分,但在某些方面是文档的元数据。我还考虑了一个POST/document

我有一个资源,它本质上是一个简单的CRUD文档,它有一个小小的转折点,它可以“切换”到“同步”状态,在这种状态下,它不再使用自己的当前值,而是返回它现在与之同步的“父”文档的值

我正试图找到一种RESTful的建模方法。该资源有一个属性指示此状态
synchronized=true/false
,还有一个
ParentId
属性指示它与哪个资源同步

一种选择是只允许在
PUT
更新过程中更改此项,但这感觉有点不正确,因为这不是文档的一部分,但在某些方面是文档的元数据。我还考虑了一个
POST/document/{id}/synchronized
请求,其中请求的状态作为参数传递


但两人都感觉不太对。第一个感觉有点尴尬,因为它感觉好像我正在为一个值解析提交的数据,如果我们正在同步,其余的基本上被丢弃。在第二种情况下,仅为一个属性创建嵌套资源感觉是错误的PATCH方法指定要应用于文档的一组更改,而不是替换整个文档(通过
PUT

(如果您只想检索文档的一部分,请考虑指定一个带有<代码> GET。您需要定义一个字节范围以外的东西来处理XML或JSON文档——请参阅详细信息。)


显然,这两种解决方案都假定有一个愿意的客户端和服务器——如果你不能支持请求两端的API,那么你也不会有太大的成功。

< P>你可以考虑,响应一个同步资源上的get,返回一个带有位置头集的302/303到父资源。但随后允许对同一个同步URI进行PUT,以将重定向替换为已传输的实体,该实体随后将在后续GET响应中返回。如果希望允许客户端将实体切换回同步状态,可以通过向子URI发布包含所需父URI的请求正文来实现。您甚至可以通过允许客户端发布任何URI(而不仅仅是一小部分已知父级的id)来发现意外的用例

GET /child
    200 OK
    {foo: bar}

POST /child
{parent: /some/other}
    200 OK

GET /child
    302/303
    Location: /some/other

PUT /child
{foo: baz}
    201 Created

GET /child
    200 OK
    {foo: baz}

这里的一个解决方案是使用两种不同的资源类型—完整文档和从属文档—通过MIME类型进行区分。例如,您可以使用
application/vnd.mysite.document
作为完整文档,而当您仅链接到另一个文档时,可以使用
application/vnd.mysite.documentlink+json

要制作从属文档,请执行以下操作:

PUT /document/1234
Content-Type: application/vnd.mysite.documentlink+json

{"parent": "/document/1"}
PUT /document/1234
Content-Type: application/vnd.mysite.document

Hello, I am a document full of stuff.
要制作完整的文档,请执行以下操作:

PUT /document/1234
Content-Type: application/vnd.mysite.documentlink+json

{"parent": "/document/1"}
PUT /document/1234
Content-Type: application/vnd.mysite.document

Hello, I am a document full of stuff.

然后,您可以通过返回文档或将303(参见其他)重定向到父级来响应
GET
请求。

是的,这与我很快想到的方向非常相似。虽然这需要相当多的重构,但我认为这是理想的方法。虽然我想我会避免自定义mimetype,现在只使用纯JSON。我想避免使用补丁方法。不管怎么说,这并不是一个真正的补丁。如果我理解正确的话,似乎“切换”状态与REST不一致,因为它不再是相同的资源。但是,如果资源没有转换为新资源,并且您希望能够访问这两种格式,我肯定会选择内容类型协商,因为您只是以不同的方式表示资源,而不是创建新的资源。