首页 > 解决方案 > REST API 中下载的正确 http 动词是什么?

问题描述

我遇到过我不确定 Endpoint 是否应该回答 POST 或 GET 请求的情况。

情况:

我有一个Reports以 UUID 作为主键的数据库表。用户应该能够Report根据存储在不同表中的一些逻辑和数据创建一个 PDF 格式。

现在我实现了一个端点,reports/<uuid>/export它是一个 GET 端点。

但是,在实现这个之后,我很好奇:GET 甚至是这个端点的正确 HTTP 动词/请求类型吗?

或更笼统地说:对于提供主键的资源下载的端点,正确的 HTTP 动词是什么?

标签: resthttppostgetrequest

解决方案


对于提供主键的资源下载的端点,正确的 HTTP 动词是什么?

简短的回答是GET语义通常是您想要使用的。

请求方法令牌是请求语义的主要来源;它指示客户端发出此请求的目的以及客户端期望的成功结果。 RFC-7231;第 4.1 节

GET 方法请求传输目标资源的当前选定表示。GET 是信息检索的主要机制,也是几乎所有性能优化的重点。因此,当人们谈到通过 HTTP 检索某些可识别信息时,他们通常指的是发出 GET 请求。 RFC-7231;第 4.3.1 节

资源由它们的 URI 标识;下面的两个请求针对不同的资源:

GET /example?uuid=764baee2-c5be-49cc-ac83-c9d1ea61d68a HTTP/1.1
GET /example?uuid=3b90b949-911c-433c-bec4-e6063f5377e0 HTTP/1.1

从 REST 的角度来看,尽管底层实现(也称为“端点”)可能相同,但它们是不同的。

您可以将 URI 本身视为用于在文档存储中查找资源的键。

更常见的是,我们将使用某种形式的模板从目标 uri 中提取我们在服务器上访问数据所需的特定信息——例如,从查询部分中提取 uuid 参数并将其用作主要信息钥匙。

这是理想的设置:如果请求语义实际上是只读的,并且我们期望返回资源的表示(例如,PDF),那么GET这就是我们想要的方法。

有时情况并不理想:当我们需要请求正文中包含的信息来做正确的事情时,就会出现这种情况。GET在 HTTP 中,请求上的有效负载(消息体)没有定义的语义。因此,如果您需要在请求中有正文,则GET超出范围,您可能会使用它POST

在实践中发现了对请求行长度的各种特殊限制。建议所有 HTTP 发送方和接收方至少支持 8000 个八位字节的请求行长度。 RFC-7230;第 3.1.1 节

除非您控制客户端,否则您可能无法确保支持 8000 个八位字节。因此,您通常会以更简单的资源标识符和大量信息编码到消息体(想想SOAPGraphQLPOST作为请求方法结束,因为其他方法的语义不适合。

这并不理想,因为类似资源的 PDF 表示应该是可缓存的,但 HTTP 缓存的语义不支持请求的消息体必须是缓存键的一部分的用例。见马克诺丁汉 2012-09-04


推荐阅读