17

我正在设计一个 API,我想知道在 GET 请求上发送 JSON 有效负载是否可以?

在HTTP 请求方法的这个其他问题中,我们可以根据这个链接找到:

  • HEAD - 没有定义的正文语义。
  • GET - 没有定义的正文语义。
  • PUT - 支持身体。
  • POST - 支持正文。
  • DELETE - 没有定义的正文语义。
  • TRACE - 不支持正文。
  • 选项 - 支持正文但没有语义(可能在将来)。

这是否意味着我不应该发送带有有效负载的 GET 请求? 这样做有风险吗?

  • 就像某些 HTTP 客户端库无法发送这样的有效负载一样?
  • 或者我的 Java API 代码不能在某些应用服务器上移植?
  • 还要别的吗?

我发现 ElasticSearch 在 GET 请求中使用了这样的有效负载:

$ curl -XGET 'http://localhost:9200/twitter/tweet/_search?routing=kimchy' -d '{
    "query": {
        "filtered" : {
            "query" : {
                "query_string" : {
                    "query" : "some query string here"
                }
            },
            "filter" : {
                "term" : { "user" : "kimchy" }
            }
        }
    }
}
'

因此,如果这个受欢迎的图书馆做到了并且没有人抱怨,那么也许我也可以这样做?

顺便说一句,我想知道混合 queryString 参数和 JSON 有效负载是否可以?就像这个 ElasticSearch 查询一样。如果是这样,是否有规则让我们知道哪些参数应该是 queryString 参数或有效负载参数?


在这里我们可以阅读: HTTP GET with request body

Roy Fielding 关于在 GET 请求中包含正文的评论。

是的。换句话说,任何 HTTP 请求消息都被允许包含消息体,因此必须考虑到这一点来解析消息。但是,GET 的服务器语义受到限制,因此主体(如果有)对请求没有语义意义。解析的要求与方法语义的要求是分开的。

所以,是的,您可以使用 GET 发送正文,但不,这样做从来没有用处。

这是 HTTP/1.1 分层设计的一部分,一旦规范被划分(正在进行中),它​​将再次变得清晰。

....罗伊

然后我真的不明白为什么它从来没有用,因为在我看来,将复杂的查询发送到不适合 queryParam 或 matrixParam 的服务器是有意义的。我认为 ElasticSearch API 的设计者也是这么想的……


我打算设计一个可以这样调用的API:

curl -XGET 'http://localhost:9000/documents/inbox?pageIndex=0&pageSize=10&sort=title'

curl -XGET 'http://localhost:9000/documents/trash?pageIndex=0&pageSize=10&sort=title'

curl -XGET 'http://localhost:9000/documents/search?pageIndex=0&pageSize=10&sort=title' -d '{
    "someSearchFilter1":"filterValue1",
    "someSearchFilter2":"filterValue2",
    "someSearchFilterList": ["filterValue3","xxx"]
    ... a lot more ...
}
'

你觉得还好吗?基于以上考虑。


4

4 回答 4

3

让 GET 响应根据请求正文而变化将破坏缓存。不要去那里。

于 2013-05-03T14:30:18.653 回答
3

另请参阅:HTTP GET with request body - 了解更多详情。

要点是:是的,您可以,但出于各种原因,您可能不应该这样做,包括:

  • 您可能会忽略 HTTP 规范建议(您可能想要发布)
  • 您可能会引入缓存问题
  • 就 REST API 而言,这并不直观
于 2017-01-19T09:30:32.727 回答
2

Google App Engine 是一个流行的 Web 框架,它使用一个特殊的 url 获取库,它不支持使用有效负载发出 HTTP GET 请求。因此,如果您希望您的 API 能够覆盖 Google App Engine 用户,那么我不建议您要求这种行为。

我已经用谷歌打开了一个关于这个的问题

于 2014-01-20T08:03:39.150 回答
0

仅仅因为您可以做某事,并不意味着您应该做某事。如果这听起来令人气愤的重复,我很抱歉,但是关于标准的事情是它们是标准的——而 HTTP 是最成熟的标准之一。它并不完美,很多人都想改变很多东西,但事实上几乎每个人仍在使用 URL 参数来处理诸如此类的用例,这足以表明没有现在任何可靠的替代品。

speedplane 和 Julian Reschke 的回答给出了两个具体的例子,说明如果你依赖带有 body/payload 的 GET 请求,这些事情将会中断。如果您愿意,您可以以与其他人不同的方式编写您的应用程序,但网络是一个可能比平时更重视标准的领域。我知道成为开拓者很诱人,但恕我直言,请考虑存在多少网站,以及有多少网络程序员正在构建和维护它们。如果有明确更好的方法,您现在很可能会看到它在生产中广泛使用。

标准变化/采用缓慢,因为必须有很多人同意它们才能工作。您说有些应用程序违反了规则是正确,但是您会注意到它们给人们带来了麻烦,并且在某些情况下需要解决方法/冗余措施,正如 Aetherus 在对另一个答案的评论中提到的那样。在这样的问题上,我倾向于走阻力最小的道路。如果你真的想这样做,我相信你可以让它发挥作用。

于 2016-02-17T02:55:25.783 回答