由于某些原因,我的应用程序需要一个 API,其流程如下:
- 客户端调用服务器以获取新资源的 ID。
- 然后用户花一些时间填写资源的表格。
- 然后用户单击保存(或不...),当他这样做时,客户端通过写入保存
/myresource/{id}
设计这个的 RESTful 方式是什么?
第一个电话应该是什么样子?在服务器端,这是一个生成 ID 并返回它的问题。它有副作用(增加序列并因此“保留空间”),但它没有显式创建资源。
如果我理解正确,第三次调用应该是 PUT,因为它创建了具有已知 URI 的东西。
您可以这样做的一种方法是:
POST的空身体/myresource/302 (Found)进行响应,Location响应头设置为/myresource/newresourceid(以指示应用于创建资源的 ID/URI)PUT成为新资源。/myresource/newresourceid似乎足够RESTful。;)
我有兴趣看到这个问题的其他答案,因为我想有很多方法可以做到这一点。
如果可能的话,我会让您在数据库中的自动递增 ID 作为您的代理键,并分配另一个字段作为您的业务标识符。它可能是产品代码或GUID之类的东西。
考虑到这一点,客户端现在可以自己创建ID,这完全不需要第 1 步。/myresource/MLN5001他们会对 url 执行 PUT操作,例如/myresource/3F2504E0-4F89-11D3-9A0C-0305E82C3301创建资源。如果 ID 已在使用中,则返回409 Conflict与响应正文中的冲突。否则返回201 Created并在响应正文和位置标头中包含资源的 URI。
ID 分配是非幂等的——分配操作的两次调用将获得不同的 ID——所以它应该始终是一个 POST。从那时起,资源应该在概念上存在。但是,此时我要做的是用合理的默认值填充它(无论是涉及执行 POST 还是 PUT,对于整体设计的 REST 性来说都是无关紧要的),因此用户可以花时间来改变这些东西他们想要看起来像他们想要的那样。
那么问题就变成了是否应该有某种“释放这个;我已经完成了修改它”的操作。严格的 RESTfulness 说不应该,好像你知道资源标识符(URL)然后你可以谈论它。另一方面,这并不意味着托管服务器必须将资源告诉其他任何人,直到创建用户对它感到满意为止。一般 HATEOAS 原则没有说明其他人何时可以发现资源存在,或者知道名称是否可以让您阅读内容,但是在资源所有者打开“make this”之前,向第三方否认资源存在是完全合理的公共”标志。
我会去
GET /myresource/new-id
POST /myresource/{id}
您的演练在动词上非常清楚:
- “获取新资源的 [an] ID”
您可以将 new-id 重命名为您认为最清楚的名称。如果您有多个需要执行此操作的资源,最好将生成器拆分为自己的资源,例如
GET /id-generator/myresource
GET /id-generator/my-other-resource
如果有多种情况,用户将很快了解到他们需要点击 id-generator 来获取他们的 ID。如果只是一种情况,他们只需要不经常使用它就很烦人。
我想你也可以
GET /myresource-id-generator/next
这看起来更清晰一些,但是如果您需要生成另一个 ID,则必须创建另一个资源来执行此操作。