转换数据时的 REST 约定

REST convention when transforming data

我使用 Laravel 作为 REST API 服务来上传和存储图书。 图书服务遵循标准的 REST 约定:

GET: /api/books and /api/books/<book_id> for retrieving book(s)

PUT: /api/books/<book_id> for updating a book

POST: /api/books for adding a new book

DELETE: /api/books/<book_id> for deleting a book

到目前为止一切顺利。

现在我需要另一个端点,它应该用于从一本书和一些图像中创建一个 Zip 文件。所以这本书已经在服务器上(在数据库中)。图片需要客户端临时上传,不保存在服务器上。然后将图像和书籍压缩,并将生成的文件返回给客户端。

所以我需要一个像 /api/books/{book_id}/compress 这样的端点。调用此端点时,客户端将图像附加到请求正文中。 如何以 RESTful 方式表达? 那应该是 GET 还是 POST 请求?此端点不会在服务器上存储任何内容,因此从我的角度来看,它应该是一个 GET 请求。但是如果是GET的话,能不能在request body中添加图片呢?因为这实际上应该由 POST 请求处理。

你问的真有趣。我以前有过同样的问题,我记得有人告诉我 GET 请求本来就没有请求体。但是我认为(所以我不确定)它仍然是可能的。不幸的是我找不到那个例子。

根据 w3 documentationPOST 请求可用于以下用途:

  • Annotation of existing resources;
  • Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles;
  • Providing a block of data, such as the result of submitting a form, to a data-handling process;
  • Extending a database through an append operation.

我认为您的情况是“向 data-handling 进程提供数据块,例如提交表单的结果;”适用于此。

就我个人而言,我非常严格地遵循路由定义中的特定模式及其目的:/{resource}/{identifier?}/{relatedResource?|action?}

在这种情况下,我会同意 /api/books/{book_id}/compress,因为它符合 POST.

列出的用例

But if it is GET, can I add images to the request body?

这不是个好主意...?

以下是当前标准对 GET

的说明

Although request message framing is independent of the method used, content received in a GET request has no generally defined semantics

A client SHOULD NOT generate content in a GET request unless it is made directly to an origin server that has previously indicated, in or out of band, that such a request has a purpose and will be adequately supported.

An origin server SHOULD NOT rely on private agreements to receive content, since participants in HTTP communication are often unaware of intermediaries along the request chain.

“没有普遍定义的语义”有点像“未定义的行为”——如果出现问题,导致 属性 丢失,责任将由您承担。


另一方面:it is okay to use POST.

POST serves many useful purposes in HTTP, including the general purpose of "this action isn’t worth standardizing." -- Fielding, 2009


今天,我们没有结合 safe semantics 和请求负载的标准化 HTTP 方法。

但是:有一个 work in progress 旨在支持请求正文中的查询,结果可能会发现相同的语义可用于转换。