REST API - 为什么要使用PUT DELETE POST GET?

时间:2011-01-01 05:57:07

标签: php json api rest soap

所以,我正在浏览一些有关创建REST API的文章。 其中一些建议使用所有类型的HTTP请求:例如PUT DELETE POST GET。 我们将创建例如 index.php 并以这种方式编写API:

$method = $_SERVER['REQUEST_METHOD'];
$request = split("/", substr(@$_SERVER['PATH_INFO'], 1));

switch ($method) {
  case 'PUT':
    ....some put action.... 
    break;
  case 'POST':
    ....some post action.... 
    break;
  case 'GET':
    ....some get action.... 
    break;
  case 'DELETE':
    ....some delete action.... 
    break;
}

好的,被授予 - 我对Web服务还不太了解(还)。 但是,通过常规POSTGET(包含方法名称和所有参数)接受 JSON 对象不是更容易,然后以JSON方式响应。我们可以通过PHP的json_encode()json_decode()轻松地序列化/反序列化,并且无需处理不同的HTTP请求方法即可对数据执行任何操作。

我错过了什么吗?

更新1:

好的 - 在深入了解各种API并了解了很多关于 XML-RPC JSON-RPC SOAP REST之后我得出结论,这种类型的API是合理的。实际上堆栈交换几乎都在他们的网站上使用这种方法,我确实认为这些人知道他们在做什么Stack Exchange API

9 个答案:

答案 0 :(得分:193)

RE 表示 S tate T 转移的想法不是以最简单的方式访问数据。

您建议使用帖子请求来访问JSON,这是访问/操作数据的完美有效方式。

REST是有意义数据访问的方法。当您在REST中看到请求时,它应立即显示数据发生的情况。

例如:

GET: /cars/make/chevrolet

可能会返回一系列雪佛兰汽车。 一个好的REST api甚至可以在查询字符串中加入一些输出选项,如?output=json?output=html,这将允许访问者决定应该编码信息的格式。

在考虑如何合理地将数据类型合并到REST API之后,我得出结论,明确指定数据类型的最佳方式是通过现有的文件扩展名,例如.js.json.html.xml。丢失的文件扩展名默认为默认格式(例如JSON);不受支持的文件扩展名可能会返回501 Not Implemented status code

另一个例子:

POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }

可能会在数据库中使用相关颜色创建一个新的chevy malibu。我说可能因为REST api不需要与数据库结构直接相关。它只是一个屏蔽接口,以便保护真实数据(将其视为数据库结构的访问器和变换器)。

现在我们需要讨论idempotence的问题。通常,REST通过HTTP实现CRUD。 HTTP对请求使用GETPUTPOSTDELETE

一个非常简单的REST 实现可以使用以下CRUD映射:

Create -> Post
Read   -> Get
Update -> Put
Delete -> Delete

此实现存在问题:Post被定义为非幂等方法。这意味着后续调用相同的Post方法将导致不同的服务器状态。获取,放置和删除是幂等的;这意味着多次调用它们会导致服务器状态相同。

这意味着请求如:

Delete: /cars/oldest

实际上可以实现为:

Post: /cars/oldest?action=delete

尽管

Delete: /cars/id/123456
如果你调用一次,或者你调用它1000次,

将导致相同的服务器状态。

处理删除oldest项目的更好方法是请求:

Get: /cars/oldest

并使用结果数据中的ID发出delete请求:

Delete: /cars/id/[oldest id]

如果在请求/cars和发出/oldest之间添加了另一个delete项,则此方法存在问题。

答案 1 :(得分:38)

这是一个安全性和可维护性问题。

安全方法

只要有可能,您应该使用“安全”(单向)方法,例如GET和HEAD,以限制潜在的漏洞。

幂等方法

只要有可能,你应该使用'幂等'方法,如GET,HEAD,PUT和DELETE,它们不会产生副作用,因此不易出错/易于控制。

Source

答案 2 :(得分:24)

简而言之,REST强调动词上的名词。随着API变得越来越复杂,您需要添加更多内容,而不是更多命令。

答案 3 :(得分:9)

你问过

  

通过正常的$ _POST接受JSON对象然后以JSON响应也不容易

来自REST上的维基百科:

  

RESTful应用程序可以最大限度地利用所选网络协议提供的预先存在的,定义良好的界面和其他内置功能,并最大限度地减少新应用程序特定功能的添加

从我所看到的(很少),我相信这通常是通过最大限度地使用现有的HTTP动词,并为您的服务设计尽可能强大且不言自明的URL方案来实现的。

不建议使用自定义数据协议(即使它们是基于标准数据协议构建的,例如SOAP或JSON),应尽量减少这些协议以最好地符合REST意识形态。

  另一方面,SOAP RPC over HTTP鼓励每个应用程序设计者定义一个新的和任意的名词和动词词汇表(例如getUsers(),savePurchaseOrder(...)),通常覆盖在HTTP'POST上'动词。这忽略了HTTP的许多现有功能,例如身份验证,缓存和内容类型协商,并且可能让应用程序设计人员在新词汇表中重新发明许多这些功能。

您正在使用的实际对象可以采用任何格式。我们的想法是尽可能多地重用HTTP来公开用户想要对这些资源执行的操作(查询,状态管理/变异,删除)。

你问过

  

我错过了什么吗?

还有很多关于REST和URI语法/ HTTP动词本身的知识。例如,一些动词是幂等的,而另一些则不是。我在你的问题中没有看到任何相关内容,所以我没有费心去尝试。其他答案和维基百科都有很多好的信息。

此外,如果您使用的是真正安静的API,那么您可以了解基于HTTP构建的各种网络技术,您可以充分利用这些技术。我将从身份验证开始。

答案 4 :(得分:8)

关于使用扩展来定义数据类型。 我注意到MailChimp API正在这样做,但我认为这不是一个好主意。

GET /zzz/cars.json/1

GET /zzz/cars.xml/1

我的声音听起来不错,但我认为“较旧”的方法更好 - 使用HTTP标头

GET /xxx/cars/1
Accept: application/json

对于跨数据类型的通信(如果有人需要它),HTTP标头也要好得多。

POST /zzz/cars
Content-Type: application/xml     <--- indicates we sent XML to server
Accept: application/json          <--- indicates we want get data back in JSON format  

答案 5 :(得分:4)

  

我错过了什么吗?

是。 ; - )

由于uniform interface constraint,这种现象存在。 REST喜欢使用现有的标准,而不是重新发明轮子。 HTTP标准已被证明具有高度可扩展性(Web正在运行一段时间)。我们为什么要修理一些没有破坏的东西?!

注意:如果要将客户端与服务分离,则统一接口约束很重要。它类似于为类定义接口以便将它们相互分离。 OFC。在这里,统一界面由HTTPMIME typesURIRDFlinked data vocabshydra vocab等标准组成...... / em>

答案 6 :(得分:1)

良好的语义学在编程中很重要。

除了GET / POST之外,使用更多方法会有所帮助,因为它会提高代码的可读性并使其更易于维护。

为什么?

因为您知道GET将从您的api中检索数据。您知道POST会向系统添加新数据。你知道PUT会做出更新。 DELETE将删除行等等,

我通常构建我的RESTFUL Web服务,以便我有一个与方法相同的函数回调。

我使用PHP,所以我使用function_exists(我认为它被调用)。如果该函数不存在,我抛出405(METHOD NOT ALLOWED)。

答案 7 :(得分:1)

Bill Venners:在您的博客文章“为什么REST失败”中,您说我们需要所有四个HTTP动词-GET,POST,PUT和DELETE-并感叹浏览器供应商只有GET “为什么我们需要所有四个动词?为什么GET和POST不够?”

Elliotte Rusty Harold: HTTP中有四种基本方法:GET,POST,PUT和DELETE。大部分时间都使用GET。它用于任何安全的,不会产生任何副作用。 GET可以被加入书签,缓存,链接,通过代理服务器。这是一个非常强大的操作,非常有用的操作。

相反,POST可能是最强大的操作。它可以做任何事情。对于可能发生的事情没有限制,因此,你必须非常小心。你没有为它添加书签。你没有缓存它。你不预先取它。在不询问用户的情况下,您不对POST执行任何操作。你想这样做吗?如果用户按下按钮,您可以POST一些内容。但是你不会看到页面上的所有按钮,而是开始随机按下它们。相比之下,浏览器可能会查看页面上的所有链接并预先获取它们,或者预先获取他们认为最有可能遵循的链接。事实上,一些浏览器和Firefox扩展以及各种其他工具已经尝试过这样做。

PUT和DELETE位于GET和POST之间。 PUT或DELETE与POST之间的区别在于PUT和DELETE是*幂等的,而POST则不是。如有必要,可以重复PUT和DELETE。假设您正在尝试将新页面上传到网站。假设您要在http://www.example.com/foo.html创建新页面,那么您可以输入内容并将其放在该URL上。服务器在您提供的URL处创建该页面。现在,让我们假设您的网络连接出现故障。您不确定,请求是否通过?也许网络很慢。也许有代理服务器问题。因此,再次尝试或者再次尝试它是完全可以的。因为将同一文档放到同一个URL上十次与放一次不会有任何不同。 DELETE也是如此。您可以删除十次,这与删除一次相同。

相比之下,POST可能会导致每次都发生不同的事情。想象一下,按下购买按钮即可退出在线商店。如果您再次发送该POST请求,您最终可能会再次购买购物车中的所有内容。如果你再发一次,你第三次买了它。这就是为什么浏览器必须非常小心在没有明确的用户同意的情况下重复POST操作,因为如果你做两次,POST可能会导致两件事情发生,如果你这样做三件事就会发生三件事。使用PUT和DELETE,零请求和一个请求之间存在很大差异,但是一个请求和十个请求之间没有区别。

请访问该网址了解详情。 http://www.artima.com/lejava/articles/why_put_and_delete.html

更新:

幂等方法 幂等HTTP方法是一种HTTP方法,可以多次调用而不会产生不同的结果。如果只调用一次或十次调用该方法,则无关紧要。结果应该是一样的。同样,这仅适用于结果,而不适用于资源本身。这仍然可以被操作(如更新时间戳,只要此信息不在(当前)资源表示中共享。

请考虑以下示例:

  

a = 4;

     

一个++;

第一个例子是幂等的:无论我们执行多少次这个语句,a总是为4.第二个例子不是幂等的。执行此操作10次将导致与运行5次时不同的结果。由于两个例子都在改变a的值,因此两者都是不安全的方法。

答案 8 :(得分:0)

基本上REST是(wiki):

  1. 客户端-服务器体系结构
  2. 无国籍
  3. 可缓存性
  4. 分层系统
  5. 按需编码(可选)
  6. 统一的界面

REST不是协议,而是原则。 不同的方法和方法-所谓的最佳实践。