php REST API - 为什么使用 PUT DELETE POST GET?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4573305/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
REST API - why use PUT DELETE POST GET?
提问by Stann
So, I was looking through some articles on creating REST API's.
And some of them suggest using all types of HTTP requests: like PUT
DELETE
POST
GET
.
We would create for example index.phpand write API this way:
所以,我正在浏览一些关于创建 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;
}
OK, granted - I don't know much about web services (yet).
But, wouldn't it be easier to just accept JSONobject through regular POST
or GET
(that would contain method name and all parameters) and then respond in JSON as well. We can easily serialize/deserialize via PHP's json_encode()
and json_decode()
and do whatever we want with that data without having to deal with different HTTP request methods.
好的,当然 - 我对 Web 服务知之甚少(目前)。但是,通过常规或(将包含方法名称和所有参数)接受JSON对象然后也以 JSON 响应不是更容易吗?我们可以轻松地通过 PHP 进行序列化/反序列化,并且可以对这些数据做任何我们想做的事情,而无需处理不同的 HTTP 请求方法。POST
GET
json_encode()
json_decode()
Am I missing something?
我错过了什么吗?
UPDATE 1:
更新1:
Ok - after digging through various API's and learning a lot about XML-RPC, JSON-RPC, SOAP, RESTI came to a conclusion that this type of API is sound. Actually stack exchange is pretty much using this approach on their sites and I do think that these people know what they are doing Stack Exchange API.
好的 - 在挖掘了各种 API 并学习了很多关于XML-RPC、JSON-RPC、SOAP、REST 之后,我得出的结论是这种类型的 API 是合理的。实际上堆栈交换在他们的网站上几乎使用这种方法,我确实认为这些人知道他们在做什么Stack Exchange API。
回答by zzzzBov
The idea of REpresentational State Transfer is not about accessing data in the simplest way possible.
的想法RE表象小号泰特Ť转让(BOT)是不是在可能的最简单的方法访问数据。
You suggested using post requests to access JSON, which is a perfectly valid way to access/manipulate data.
您建议使用 post 请求来访问 JSON,这是一种访问/操作数据的完全有效的方式。
REST is a methodology for meaningfulaccess of data. When you see a request in REST, it should immediately be apparant what is happening with the data.
REST 是一种有意义的数据访问方法。当您在 REST 中看到一个请求时,它应该立即清楚数据发生了什么。
For example:
例如:
GET: /cars/make/chevrolet
is likely going to return a list of chevy cars. A good REST api might even incorporate some output options in the querystring like ?output=json
or ?output=html
which would allow the accessor to decide what format the information should be encoded in.
很可能会返回雪佛兰汽车的列表。 一个好的 REST api 甚至可能会在查询字符串中包含一些输出选项,例如?output=json
或?output=html
允许访问者决定信息应该以什么格式编码。
After a bit of thinking about how to reasonably incorporate data typing into a REST API, I've concluded that the best way to specify the type of data explicitly would be via the already existing file extension such as .js
, .json
, .html
, or .xml
. A missing file extension would default to whatever format is default (such as JSON); a file extension that's not supported could return a 501 Not Implemented
status code.
关于如何合理地一体化的数据类型为REST API比特思考后,我已经得出结论,最好的办法明确指定的数据类型是通过已存在的文件扩展名,例如.js
,.json
,.html
,或.xml
。缺少的文件扩展名将默认为任何默认格式(例如 JSON);不受支持的文件扩展名可能会返回501 Not Implemented
状态代码。
Another example:
另一个例子:
POST: /cars/
{ make:chevrolet, model:malibu, colors:[red, green, blue, grey] }
is likely going to create a new chevy malibu in the db with the associated colors. I say likelyas the REST api does not need to be directly related to the database structure. It is just a masking interface so that the true data is protected (think of it like accessors and mutators for a database structure).
很可能会在数据库中使用相关颜色创建一个新的雪佛兰马里布。我说可能是因为 REST api 不需要与数据库结构直接相关。它只是一个屏蔽接口,以便保护真实数据(将其视为数据库结构的访问器和修改器)。
Now we need to move onto the issue of idempotence. Usually REST implements CRUDover HTTP. HTTP uses GET
, PUT
, POST
and DELETE
for the requests.
现在我们需要讨论幂等性问题。通常 REST通过 HTTP实现CRUD。HTTP 使用GET
, PUT
,POST
和DELETE
用于请求。
A very simplistic implementation of REST coulduse the following CRUD mapping:
REST 的一个非常简单的实现可以使用以下 CRUD 映射:
Create -> Post
Read -> Get
Update -> Put
Delete -> Delete
There is an issue with this implementation: Post is defined as a non-idempotent method. This means that subsequent calls of the same Post method will result in differentserver states. Get, Put, and Delete, are idempotent; which means that calling them multiple times should result in an identical server state.
此实现存在一个问题:Post 被定义为非幂等方法。这意味着相同 Post 方法的后续调用将导致不同的服务器状态。Get、Put 和 Delete 是幂等的;这意味着多次调用它们应该会导致相同的服务器状态。
This means that a request such as:
这意味着诸如以下的请求:
Delete: /cars/oldest
could actually be implemented as:
实际上可以实现为:
Post: /cars/oldest?action=delete
Whereas
然而
Delete: /cars/id/123456
will result in the same server state if you call it once, or if you call it 1000 times.
如果您调用一次或调用 1000 次,将导致相同的服务器状态。
A better way of handling the removal of the oldest
item would be to request:
处理删除oldest
项目的更好方法是请求:
Get: /cars/oldest
and use the ID
from the resulting data to make a delete
request:
并使用ID
结果数据发出delete
请求:
Delete: /cars/id/[oldest id]
An issue with this method would be if another /cars
item was added between when /oldest
was requested and when the delete
was issued.
这种方法的一个问题是,是否/cars
在/oldest
请求和delete
发布之间添加了另一个项目。
回答by markus
This is a security and maintainability question.
这是一个安全性和可维护性问题。
safe methods
安全的方法
Whenever possible, you should use 'safe' (unidirectional) methods such as GET and HEAD in order to limit potential vulnerability.
只要有可能,您应该使用“安全”(单向)方法,例如 GET 和 HEAD,以限制潜在的漏洞。
idempotent methods
幂等方法
Whenever possible, you should use 'idempotent' methods such as GET, HEAD, PUT and DELETE, which can't have side effects and are therefore less error prone/easier to control.
只要有可能,您应该使用“幂等”方法,例如 GET、HEAD、PUT 和 DELETE,它们不会产生副作用,因此更不容易出错/更易于控制。
回答by Neil
In short, REST emphasizes nouns over verbs. As your API becomes more complex, you add more things, rather than more commands.
简而言之,REST 强调名词而不是动词。随着您的 API 变得越来越复杂,您可以添加更多的东西,而不是更多的命令。
回答by Merlyn Morgan-Graham
You asked:
你问:
wouldn't it be easier to just accept JSON object through normal $_POST and then respond in JSON as well
通过普通的 $_POST 接受 JSON 对象然后也以 JSON 响应不是更容易吗
From the Wikipedia on REST:
来自REST维基百科:
RESTful applications maximize the use of the pre-existing, well-defined interface and other built-in capabilities provided by the chosen network protocol, and minimize the addition of new application-specific features on top of it
RESTful 应用程序最大限度地利用预先存在的、定义良好的接口和所选网络协议提供的其他内置功能,并最大限度地减少在其上添加特定于应用程序的新功能
From what (little) I've seen, I believe this is usually accomplished by maximizing the use of existing HTTP verbs, and designing a URL scheme for your service that is as powerful and self-evident as possible.
从我所看到的(一点点)来看,我相信这通常是通过最大限度地使用现有的 HTTP 动词来实现的,并为您的服务设计一个尽可能强大和不言自明的 URL 方案。
Custom data protocols (even if they are built on top of standard ones, such as SOAP or JSON) are discouraged, and should be minimized to best conform to the REST ideology.
不鼓励使用自定义数据协议(即使它们建立在标准协议之上,例如 SOAP 或 JSON),并且应该将其最小化以最好地符合 REST 意识形态。
SOAP RPC over HTTP, on the other hand, encourages each application designer to define a new and arbitrary vocabulary of nouns and verbs (for example getUsers(), savePurchaseOrder(...)), usually overlaid onto the HTTP 'POST' verb. This disregards many of HTTP's existing capabilities such as authentication, caching and content type negotiation, and may leave the application designer re-inventing many of these features within the new vocabulary.
另一方面,SOAP RPC over HTTP 鼓励每个应用程序设计人员定义一个新的、任意的名词和动词词汇表(例如 getUsers()、savePurchaseOrder(...)),通常覆盖在 HTTP 'POST' 动词上。这忽略了 HTTP 的许多现有功能,例如身份验证、缓存和内容类型协商,并且可能让应用程序设计人员在新词汇表中重新发明其中的许多功能。
The actual objects you are working with can be in any format. The idea is to reuse as much of HTTP as possible to expose your operations the user wants to perform on those resource (queries, state management/mutation, deletion).
您正在使用的实际对象可以是任何格式。这个想法是尽可能多地重用 HTTP 来公开用户想要对这些资源执行的操作(查询、状态管理/变异、删除)。
You asked:
你问:
Am I missing something?
我错过了什么吗?
There is a lot more to know about REST and the URI syntax/HTTP verbs themselves. For example, some of the verbs are idempotent, others aren't. I didn't see anything about this in your question, so I didn't bother trying to dive into it. The other answers and Wikipedia both have a lot of good information.
关于 REST 和 URI 语法/HTTP 动词本身,还有很多需要了解的地方。例如,有些动词是幂等的,有些则不是。我在你的问题中没有看到任何关于这一点的内容,所以我没有费心去深入研究它。其他答案和维基百科都有很多很好的信息。
Also, there is a lot to learn about the various network technologies built on top of HTTP that you can take advantage of if you're using a truly restful API. I'd start with authentication.
此外,如果您使用的是真正的宁静 API,则有很多关于构建在 HTTP 之上的各种网络技术的知识需要了解,您可以利用这些技术。我会从身份验证开始。
回答by Pawel Cioch
In regards to using extension to define data type. I noticed that MailChimp API is doing it, but I don't think this is a good idea.
关于使用扩展来定义数据类型。我注意到 MailChimp API 正在这样做,但我认为这不是一个好主意。
GET /zzz/cars.json/1
GET /zzz/cars.xml/1
My sound like a good idea, but I think "older" approach is better - using HTTP headers
我的想法听起来不错,但我认为“旧”方法更好 - 使用 HTTP 标头
GET /xxx/cars/1
Accept: application/json
Also HTTP headers are much better for cross data type communication (if ever someone would need it)
此外,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
回答by inf3rno
Am I missing something?
我错过了什么吗?
Yes. ;-)
是的。;-)
This phenomenon exists because of the uniform interface constraint. REST likes using already existing standards instead of reinventing the wheel. The HTTP standard has already proven to be highly scalable (the web is working for a while). Why should we fix something which is not broken?!
这种现象的存在是由于统一的界面约束。REST 喜欢使用已经存在的标准,而不是重新发明轮子。HTTP 标准已经被证明是高度可扩展的(网络已经运行了一段时间)。为什么我们要修理没有损坏的东西?!
note: The uniform interface constraint is important if you want to decouple the clients from the service. It is similar to defining interfaces for classes in order to decouple them from each other. Ofc. in here the uniform interface consists of standards like HTTP, MIME types, URI, RDF, linked data vocabs, hydra vocab, etc...
注意:如果要将客户端与服务分离,统一接口约束很重要。它类似于为类定义接口以将它们彼此解耦。办公室 在这里统一的接口包括像标准的HTTP,MIME类型,URI,RDF,链接数据vocabs,水螅词汇,等等。
回答by HumbleWebDev
Good Semantics is important in programming.
良好的语义在编程中很重要。
Utilizing more methods besides GET/POST will be helpful because it will increase the readability of your code and make it easier to maintain.
使用除 GET/POST 之外的更多方法会很有帮助,因为它会提高代码的可读性并使其更易于维护。
Why?
为什么?
Because you know GET will retrieve data from your api. You know POST will add new data to your system. You know PUT will make updates. DELETE will delete rows etc, etc,
因为您知道 GET 将从您的 api 中检索数据。您知道 POST 会向您的系统添加新数据。您知道 PUT 会进行更新。DELETE 将删除行等,等等,
I normally structure my RESTFUL Web Services so that I have a function callback named the same thing as the method.
我通常构建我的 RESTFUL Web 服务,以便我有一个与方法名称相同的函数回调。
I use PHP, so I use function_exists (I think its called). If the function doesn't exist, I throw a 405 (METHOD NOT ALLOWED).
我使用 PHP,所以我使用 function_exists (我认为它被称为)。如果该函数不存在,我会抛出 405(不允许的方法)。
回答by Bimal Das
Bill Venners:In your blog post entitled "Why REST Failed," you said that we need all four HTTP verbs—GET, POST, PUT, and DELETE— and lamented that browser vendors only GET and POST." Why do we need all four verbs? Why aren't GET and POST enough?
Bill Venners:在你题为“为什么 REST 失败”的博文中,你说我们需要所有四个 HTTP 动词——GET、POST、PUT 和 DELETE——并感叹浏览器供应商只有 GET 和 POST。”为什么我们需要所有四个动词动词?为什么 GET 和 POST 不够?
Elliotte Rusty Harold:There are four basic methods in HTTP: GET, POST, PUT, and DELETE. GET is used most of the time. It is used for anything that's safe, that doesn't cause any side effects. GET is able to be bookmarked, cached, linked to, passed through a proxy server. It is a very powerful operation, a very useful operation.
Elliotte Rusty Harold:HTTP 中有四种基本方法:GET、POST、PUT 和 DELETE。大多数时候使用 GET。它用于任何安全的,不会引起任何副作用的东西。GET 能够被添加书签、缓存、链接到、通过代理服务器传递。这是一个非常强大的操作,一个非常有用的操作。
POST by contrast is perhaps the most powerful operation. It can do anything. There are no limits as to what can happen, and as a result, you have to be very careful with it. You don't bookmark it. You don't cache it. You don't pre-fetch it. You don't do anything with a POST without asking the user. Do you want to do this? If the user presses the button, you can POST some content. But you're not going to look at all the buttons on a page, and start randomly pressing them. By contrast browsers might look at all the links on the page and pre-fetch them, or pre-fetch the ones they think are most likely to be followed next. And in fact some browsers and Firefox extensions and various other tools have tried to do that at one point or another.
相比之下,POST 可能是最强大的操作。它可以做任何事情。可能发生的事情没有限制,因此,您必须非常小心。你不给它添加书签。你不缓存它。你不预取它。在不询问用户的情况下,您不会对 POST 执行任何操作。你想这样做吗?如果用户按下按钮,您可以发布一些内容。但是您不会查看页面上的所有按钮,然后开始随机按下它们。相比之下,浏览器可能会查看页面上的所有链接并预取它们,或者预取他们认为接下来最有可能被访问的链接。事实上,一些浏览器和 Firefox 扩展程序以及各种其他工具曾在某个时候尝试过这样做。
PUT and DELETE are in the middle between GET and POST. The difference between PUT or DELETE and POST is that PUT and DELETE are *idempotent, whereas POST is not. PUT and DELETE can be repeated if necessary. Let's say you're trying to upload a new page to a site. Say you want to create a new page at http://www.example.com/foo.html, so you type your content and you PUT it at that URL. The server creates that page at that URL that you supply. Now, let's suppose for some reason your network connection goes down. You aren't sure, did the request get through or not? Maybe the network is slow. Maybe there was a proxy server problem. So it's perfectly OK to try it again, or again—as many times as you like. Because PUTTING the same document to the same URL ten times won't be any different than putting it once. The same is true for DELETE. You can DELETE something ten times, and that's the same as deleting it once.
PUT 和 DELETE 介于 GET 和 POST 之间。PUT 或 DELETE 和 POST 之间的区别在于 PUT 和 DELETE 是 *幂等的,而 POST 不是。如有必要,可以重复 PUT 和 DELETE。假设您正在尝试将新页面上传到站点。假设您想在http://www.example.com/foo.html创建一个新页面,所以你输入你的内容,然后把它放在那个 URL 上。服务器在您提供的 URL 上创建该页面。现在,让我们假设由于某种原因您的网络连接出现故障。您不确定,请求是否通过?可能网速慢。可能是代理服务器问题。所以再试一次,或者再试一次——只要你喜欢,就可以。因为将同一个文档放入同一个 URL 十次与放入一次没有任何不同。DELETE 也是如此。你可以删除一个东西十次,这和删除一次是一样的。
By contrast, POST, may cause something different to happen each time. Imagine you are checking out of an online store by pressing the buy button. If you send that POST request again, you could end up buying everything in your cart a second time. If you send it again, you've bought it a third time. That's why browsers have to be very careful about repeating POST operations without explicit user consent, because POST may cause two things to happen if you do it twice, three things if you do it three times. With PUT and DELETE, there's a big difference between zero requests and one, but there's no difference between one request and ten.
相比之下,POST 可能会导致每次发生不同的事情。想象一下,您正在通过按购买按钮结帐在线商店。如果您再次发送该 POST 请求,您最终可能会再次购买购物车中的所有商品。如果你再次发送它,你已经第三次购买了。这就是为什么浏览器必须非常小心在没有明确用户同意的情况下重复 POST 操作,因为 POST 可能会导致两件事发生,如果你做两次,三件事如果你做三次。对于 PUT 和 DELETE,零个请求和一个请求之间存在很大差异,但一个请求和十个请求之间没有区别。
Please visit the url for more details.http://www.artima.com/lejava/articles/why_put_and_delete.html
请访问网址了解更多详情。http://www.artima.com/lejava/articles/why_put_and_delete.html
Update:
更新:
Idempotent methodsAn idempotent HTTP method is a HTTP method that can be called many times without different outcomes. It would not matter if the method is called only once, or ten times over. The result should be the same. Again, this only applies to the result, not the resource itself. This still can be manipulated (like an update-timestamp, provided this information is not shared in the (current) resource representation.
幂等方法幂等 HTTP 方法是可以多次调用而不会产生不同结果的 HTTP 方法。方法是只调用一次还是十次都没有关系。结果应该是一样的。同样,这仅适用于结果,而不适用于资源本身。这仍然可以被操纵(如更新时间戳,前提是此信息未在(当前)资源表示中共享。
Consider the following examples:
考虑以下示例:
a = 4;
a++;
一 = 4;
一个++;
The first example is idempotent: no matter how many times we execute this statement, a will always be 4. The second example is not idempotent. Executing this 10 times will result in a different outcome as when running 5 times. Since both examples are changing the value of a, both are non-safe methods.
第一个例子是幂等的:无论我们执行多少次这个语句,a 总是 4。第二个例子不是幂等的。执行此 10 次将导致与运行 5 次时不同的结果。由于两个示例都在更改 a 的值,因此它们都是非安全方法。
回答by M-A-X
Basically REST is (wiki):
基本上 REST 是(维基):
- Client–server architecture
- Statelessness
- Cacheability
- Layered system
- Code on demand (optional)
- Uniform interface
- 客户端-服务器架构
- 无国籍状态
- 可缓存性
- 分层系统
- 按需编码(可选)
- 统一界面
REST is not protocol, it is principles. Different uris and methods - somebody so called best practices.
REST 不是协议,而是原则。不同的 uri 和方法 - 所谓的最佳实践。