我可以在没有 ID 的情况下 PUT 吗?

Can I PUT without an ID?

我正在设计一个 API 允许用户将文件上传到服务器的休息服务。

我认为这是一个 PUT 请求,它将转到 server/resource/ID 并在 json 请求正文中将文件作为 base64。

我的问题是关于这个 ID。在我看来,我正在将文件传递给服务器,服务器应该负责存储该文件并生成一个唯一的 ID 以便稍后检索它,然后 return 这个 ID 以 ok 状态发送给客户端.

所以我正在考虑这样做,将它发送到 server/resource,没有 ID,但是这样可以吗还是设计不好?

没有。 PUT 表示 "create or update",并且应该带有明确的 ID。 POST适合创造新事物。

另请参阅:PUT vs POST in REST

关于问题的实际标题,我不同意@TatsuyukiIshi 给出的公认答案。 PUT 的语义是:用请求中包含的有效载荷替换给定 URI 当前可获得的内容。如果可以在没有 ID 的情况下识别资源,即可能只存在一种资源,则可以在不指定 ID 的情况下处理更新,因为 "singleton resource" 的 ID 已经在端点本身中隐式给出.不过,我不得不承认这种情况很少见。

这种情况可能是类似于资源的剪贴板,您可以在其中放置任意内容并在以后检索它。当然,您也可以使用 POST,尽管通过 POST 请求收到的 body 的语义不太清楚。另外 POSTPUT 操作相反不是幂等的。

然而,使用 PUT /api/messages 之类的东西通常意味着用请求发送的内容替换所有消息,这可能不是您真正想要的。通常您只想一次修改单个资源,因此使用标识该特定资源的随附 ID。

关于问题的实际内容,通过POST上传文件是常见的做法。上传成功后,您将 return 一个 201 Created 响应,其中包含指向生成的资源的 Location HTTP header。服务处理通过 POST 请求接收到的内容的行为完全取决于服务实施者。因此,您可以创建一个新资源,执行一些支持任务而无需任何实际资源创建或其他(规范不禁止更新)。

对你来说太晚了,但我也是同样的问题,发现了很多错误的信息,所以我会把找到的东西放在这里。

有 2 个 RFC 规定 RESTful,关于这个问题的一个是 RFC 7231,你会发现:

The PUT method requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload.

所以你不能发送没有 ID 的 PUT。

很多 RESTful API 即使在更新时也会发送 POST ,同一个 RFC 也是错误的,因此您应该始终发送 ID 以使用 PUT 创建它,或者应该使用 POST 来创建和 PUT 来更新,但请记住 POST 应该始终创建,换句话说,如果您不首先使用 GET 查找它,您将复制您的文件。

更多信息:https://www.rfc-editor.org/rfc/rfc7231#section-4.3.3