使用POST而不是GET的REST API

时间:2013-10-28 14:30:27

标签: api rest post get

让我们假设一项服务提供了一些我可以这样使用的功能:

GET /service/function?param1=value1&param2=value2

说我可以将它与POST查询一起使用是对的吗?

POST /service/function { param1 : value1, param2 : value2 }

这两个查询是否相同?我可以在任何情况下使用第二个变体,或者文档应该明确说我可以同时使用GET和POST查询吗?

8 个答案:

答案 0 :(得分:57)

只是为了审核,REST具有开发人员应遵循的某些属性,以使其成为 RESTful

什么是REST?

根据维基百科:

  

REST架构风格描述了以下六个约束   应用于架构,同时离开执行   个别组件可自由设计:

     
      
  • 客户端 - 服务器:服务器不关心用户界面或用户状态,因此服务器可以更简单,更具可扩展性。
  •   
  • 无状态:客户端 - 服务器通信受到请求之间没有客户端上下文存储在服务器上的限制。
  •   
  • 可缓存:响应必须隐式或显式地将自身定义为可缓存,以防止客户端重用陈旧或不适当的数据以响应进一步的请求。
  •   
  • 分层系统:客户端通常无法判断它是直接连接到终端服务器,还是沿途的中介。中间服务器可以通过启用负载平衡和提供共享缓存来提高系统可扩展性。
  •   
  • 按需代码(可选):服务器可以通过传输可执行代码来临时扩展或自定义客户端的功能。
  •   
  • 统一接口:下面讨论的客户端和服务器之间的统一接口简化和解耦了体系结构,使每个部分都能独立发展。 (即HTTP GET,POST,PUT,PATCH,DELETE)
  •   

动词应该做什么

SO用户 Daniel Vasallo 在问题 Understanding REST: Verbs, error codes, and authentication 中明确了这些方法的责任:

  

处理集合URI时:http://example.com/resources/

     

获取:列出集合的成员,并填写其成员   用于进一步导航的URI。例如,列出所有待售的汽车。

     

PUT:意义定义为“将整个集合替换为另一个集合   集合”。

     

POST:在分配了ID的集合中创建一个新条目   由集合自动生成。创建的ID通常包含在内   此操作返回的部分数据。

     

DELETE:含义定义为“删除整个集合”。

所以,回答你的问题:

  

说我可以在POST查询中使用它是正确的吗? ...

     

这两个查询是否相同?我可以在任何情况下使用第二个变体,或者文档应该明确说我可以同时使用GET和POST查询吗?

如果您正在编写一个普通的旧RPC API调用,只要处理服务器端在两个调用之间没有区别,它们在技术上可以互换。但是,为了使调用成为RESTful,通过GET方法调用端点应具有POST方法(即创建资源)的独特功能(即创建资源)新资源)。

旁注:关于是否还应允许POST被允许用于更新资源存在一些争论......虽然我没有对此发表评论,但我只是告诉你一些人有这个问题。

答案 1 :(得分:36)

出于以下原因,我将POST主体用于任何非平凡和业务线应用程序:

  1. 安全性 - 如果我们将GET与查询字符串和https一起使用,则查询字符串可以保存在服务器日志中并作为引用链接转发。现在,服务器/网络管理员以及用户离开您的应用后访问的下一个域都可以看到这两者。因此,如果我们发送包含机密PII数据(例如客户名称)的查询,则可能不需要。
  2. 网址最大长度 - 不是大问题,但有些浏览器的长度有限制。因此,如果我们的网址中有多个项目,例如查询,分页,要返回的字段等等。
  3. 默认情况下,帖子不是缓存。有人说需要缓存;但是,在缓存超时之前,确切客户的确切对象的完全相同的搜索条件是多少次?
  4. 顺便说一句,我也把这些字段放回我的POST主体中,因为我可能不希望暴露我的字段名称。安全就像一个洋葱;很多层,让我们哭泣!

答案 2 :(得分:32)

如果API使用POSTGET,则/service/function?param1=value1&param2=value2 无法使用这些方法进行调用。就像你的API说

一样
GET
使用POST方法访问

。然后,如果创建者未将POST方法指定为405 Method not allowed方法,则无法使用POST方法调用它。如果这样做,您可能会获得content-type状态。

通常在application/json方法中,您需要使用指定格式发送正文中的内容,该格式在GET标题中描述。 json数据POST

之后,请求主体在服务器端被反序列化。因此,您需要从客户端传递序列化数据,并由服务开发人员决定。

但一般而言,当服务器向客户端返回一些数据并且对服务器没有任何影响时使用{{1}},而{{1}}用于在服务器上创建一些资源。所以一般来说它应该不一样。

答案 3 :(得分:9)

想一想。当您的客户端向URI X发出GET请求时,它对服务器的说法是:“我希望表示位于X的资源,并且此操作不应更改服务器上的任何内容。”一个PUT请求说:“我希望你用我在这个请求的主体上给你的新实体替换位于X的资源。” DELETE请求说:“我希望您删除位于X的资源”。 PATCH说“我给你这个差异,你应该尝试将它应用到X的资源并告诉我它是否成功。”但是一个POST说:“我正在向你发送这个从属于X的资源的数据,我们之前就你应该用它做什么达成了协议。”

如果你没有在某个地方记录资源需要POST并对其执行某些操作,那么向它发送POST是没有意义的,期望它像GET一样。

REST依赖于底层协议的标准化行为,而POST恰恰是用于未标准化的操作的方法。 GET,PUT和DELETE请求的结果在标准中明确定义,但POST不是。 POST的结果从属于服务器,因此,如果没有记录您可以使用POST执行某些操作,则必须假设您不能。

答案 4 :(得分:3)

在REST中,每个HTTP谓词都有其地位和含义。

例如,

  • GET是获取网址中指向的“资源”。

  • POST用于构造后端以“创建”URL中指向的“类型”资源。 您可以使用POST调用正文中的参数或其他数据来补充POST操作。

在您的情况下,由于您有兴趣使用查询“获取”信息,因此它应该是GET操作而不是POST操作。

wiki may help进一步澄清事情。

希望这有帮助!

答案 5 :(得分:1)

REST为HTTP动词带来了意义(正如他们所定义的那样),但我更愿意同意Scott Peal。

以下是WIKI对POST request的扩展说明中的项目:

  

有时甚至HTTP GET也不太适合数据检索。这方面的一个例子是需要在URL中指定大量数据。浏览器和Web服务器可以限制它们将处理的URL的长度而不会截断或错误。 URL和查询字符串中保留字符的百分比编码可以显着增加其长度,而Apache HTTP Server可以处理URL中最多4,000个字符,[5] Microsoft Internet Explorer在任何URL中限制为2,048个字符。[6]同样,如果必须提交敏感信息(如用户名和密码)以及其他数据以完成请求,则不应使用HTTP GET。即使使用HTTPS,防止数据在传输过程中被截获,浏览器历史记录和Web服务器的日志也可能包含明文的完整URL,如果任一系统被黑客攻击,可能会暴露这些URL。在这些情况下,应该使用HTTP POST。[7]

我只能建议REST团队考虑更安全地使用HTTP协议,以避免让消费者与非安全的“良好实践”斗争。

答案 6 :(得分:0)

如果有特殊原因并正确处理,则

POST可以有效地代替GET使用。我了解它不是专门针对RESTy的,但是如果您的数据中包含大量空格,与号和斜杠等(例如,像Amazon这样的产品模型),那么尝试进行编码和解码可能会比实际值要麻烦得多,而不仅仅是对其进行预JSON化。尽管不是POST的典型用例,但请确保返回正确的响应代码并在很大程度上注释您的操作,

答案 7 :(得分:0)

如果我正确理解了这个问题,他需要执行REST GET操作,但想知道是否可以通过HTTP POST方法发送数据。

正如Scott先前在回答中很好地说明的那样,有很多充分的理由来发布输入数据。恕我直言,如果解决方案的质量是重中之重,则应采用这种方式。

前一段时间,我们创建了一个REST API来对用户进行身份验证,使用用户名/密码并返回访问令牌。该API在TLS下进行了加密,但可以公开访问公共互联网。在评估了不同的选项之后,我们选择HTTP POST作为“ GET访问令牌”的REST方法,因为这是满足安全标准的唯一方法。