理解RESTful中的方法


RESTful中的操作方法是通过HTTP协议来实现的。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、POST、PUT、DELETE。
它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。在html的世界里,'get'和'post'是最常用到的,而另外两种却很难看到,其实它们都在'http'协议的rfc文档里有定义,只因鲜有用到而不注意罢了。最常用的是get一般用于获取或查询资源,post一般用于更新资源,根据http规范:
1、get不会修改信息,只会查询信息。
2、post可以修改资源信息。
实际操作当中,get和post方法都可以实现查询,修改,增加和删除,有些开发者不按http规范操作,直接使用get方法实现资源更新,因为post方法必须使用from,会比较麻烦。
get和post的区别:
1、数据位置
(1)get请求的数据出现在url当中(http协议头),以?分割url和传输的数据,参数之间以&相连。英文字母/数字,原样发送,空格,转换为%,中文/其他字符,直接把字符串用base64加密。%xx表示xx为16进制数。
(2)post把提交数据放置在http包的包体中
2、数据长度限制
(1)受浏览器的限制,IE对url长度限制是2083字节,其他浏览器,理论上没限制,限制取决于操作系统。
(2)post理论上没有数据限制,限制取决于服务器的处理能力。
(3)iis6.0,微软出于安全考虑,加大了限制。asp post数据量最大为200kB,每个表单域限制是100kB。默认上传文件的最大为4MB。默认最大请求头是16KB。
3、安全性
(1)get以明文方式提交数据,account和password明文出现在url上,登录页面有可能被浏览器缓存,其他人查看到浏览器的历史记录,可以轻易拿到你的account和pw,还可能跨站攻击。
DELETE /uri/xxx 删除
PUT /uri/xxx 更新或创建
GET /uri/xxx 查看
GET操作是安全的
所谓安全是指不管进行多少次操作,资源的状态都不会改变。比如我用GET浏览文章,不管浏览多少次,那篇文章还在那,没有变化。当然,你可能说每浏览一次文章,文章的浏览数就加一,这不也改变了资源的状态么?这并不矛盾,因为这个改变不是GET操作引起的,而是用户自己设定的服务端逻辑造成的。
PUT,DELETE操作是幂等的
所谓幂等是指不管进行多少次操作,结果都一样。比如我用PUT修改一篇文章,然后在做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。顺便说一句,因为GET操作是安全的,所以它自然也是幂等的。
POST操作既不是安全的,也不是幂等的
比如常见的POST重复加载问题:当我们多次发出同样的POST请求后,其结果是创建出了若干的资源。
安全和幂等的意义在于:当操作没有达到预期的目标时,我们可以不停的重试,而不会对资源产生副作用。从这个意义上说,POST操作往往是有害的,但很多时候我们还是不得不使用它。
还有一点需要注意的就是,创建操作可以使用POST,也可以使用PUT,区别在于POST 是作用在一个集合资源之上的(/uri),而PUT操作是作用在一个具体资源之上的(/uri/xxx),再通俗点说,如果URL可以在客户端确定,那么就使用PUT,如果是在服务端确定,那么就使用POST,比如说很多资源使用数据库自增主键作为标识信息,而创建的资源的标识信息到底是什么只能由服务端提供,这个时候就必须使用POST。
PUT vs POST
Both PUT and POST can be used for creating.
You have to ask "what are you performing the action to?" to distinguish what you should be using. If you want to use POST then you would do that to a list of questions. If you want to use PUT then you would do that to a particular question.
Great both can be used, so which one should I use in my RESTful design:
You do not need to support both PUT and POST.
Which is used is left up to you. But just remember to use the right one depending on what object you are referencing in the request.
PUT implies putting a resource - completely replacing whatever is available at the given URL with a different thing. By definition, a PUT is idempotent. Do it as many times as you like, and the result is the same. x=5 is idempotent. You can PUT a resource whether it previously exists, or not (eg, to Create, or to Update)!
POST updates a resource, adds a subsidiary resource, or causes a change. A POST is not idempotent, in the way that x++ is not idempotent.
There seems to always be some confusion as to when to use the HTTP POST versus the HTTP PUT method for REST services. Most developers will try to associate CRUD operations directly to HTTP methods. I will argue that this is not correct and one can not simply associate the CRUD concepts to the HTTP methods. That is:
Create => HTTP PUT
Retrieve => HTTP GET
Update => HTTP POST
Delete => HTTP DELETE
It is true that the R(etrieve) and D(elete) of the CRUD operations can be mapped directly to the HTTP methods GET and DELETE respectively. However, the confusion lies in the C(reate) and U(update) operations. In some cases, one can use the PUT for a create while in other cases a POST will be required. The ambiguity lies in the definition of an HTTP PUT method versus an HTTP POST method.
According to the HTTP 1.1 specifications the GET, HEAD, DELETE, and PUT methods must be idempotent, and the POST method is not idempotent. That is to say that an operation is idempotent if it can be performed on a resource once or many times and always return the same state of that resource. Whereas a non idempotent operation can return a modified state of the resource from one request to another. Hence, in a non idempotent operation, there is no guarantee that one will receive the same state of a resource.
Based on the above idempotent definition, my take on using the HTTP PUT method versus using the HTTP POST method for REST services is:
Use the HTTP PUT method when:
The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee.
The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date).
In both cases, these operations can be performed multiple times with the same results. That is the resource will not be changed by requesting the operation more than once. Hence, a true idempotent operation.
Use the HTTP POST method when:
The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client.
On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation.
Conclusion
Do not directly correlate and map CRUD operations to HTTP methods for REST services. The use of an HTTP PUT method versus an HTTP POST method should be based on the idempotent aspect of that operation. That is, if the operation is idempotent, then use the HTTP PUT method. If the operation is non idempotent, then use the HTTP POST method.
一些注意事项
Do you name your URL objects you create explicitly, or let the server decide? If you name them then use PUT. If you let the server decide then use POST.
PUT is idempotent, so if you PUT an object twice, it has no effect. This is a nice property, so I would use PUT when possible.
You can update or create a resource with PUT with the same object URL.
With POST you can have 2 requests coming in at the same time making modifications to a URL, and they may update different parts of the object.
如何使用put、delete方法
1、在浏览器里实现
HTML forms (up to HTML version 4 and XHTML 1) only support GET and POST as HTTP request methods. A workaround for this is to tunnel other methods through POST by using a hidden form field which is read by the server and the request dispatched accordingly.
However, for the vast majority of RESTful web services GET, POST, PUT and DELETE should be sufficient. All these methods are supported by the implementations of XMLHttpRequest in all the major web browsers (IE, Firefox, Opera).
XMLHttpRequest supports every method, including CHICKEN, though some method names are matched against case-insensitively (methods are case-sensitive per HTTP) and some method names are not supported at all for security reasons.
因此,这种支持还需要浏览器的支持,着重于对'XMLHttpRequest'支持是否友好,在ajax中,是可以显示地声明用何种方法。在
jQuery.ajax()中,就可以做如下实现:
$.ajax({
url: 'script.php',
type: 'PUT',
success: function(response) {
//...
}
});
param 'type'就是需要设置的地方。
2、第三方脚本工具实现
在Perl的cpan上,通过查询'rest'的关键字就会找到不少用于校验相关功能模块及脚本,像'REST::Client'、'REST::Consumer'、' REST-Resource-client'等。
参考来源:
put-vs-post-in-rest
Hypertext Transfer Protocol -- HTTP/1.1
rest-http-post-vs-http-put
它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。在html的世界里,'get'和'post'是最常用到的,而另外两种却很难看到,其实它们都在'http'协议的rfc文档里有定义,只因鲜有用到而不注意罢了。最常用的是get一般用于获取或查询资源,post一般用于更新资源,根据http规范:
1、get不会修改信息,只会查询信息。
2、post可以修改资源信息。
实际操作当中,get和post方法都可以实现查询,修改,增加和删除,有些开发者不按http规范操作,直接使用get方法实现资源更新,因为post方法必须使用from,会比较麻烦。
get和post的区别:
1、数据位置
(1)get请求的数据出现在url当中(http协议头),以?分割url和传输的数据,参数之间以&相连。英文字母/数字,原样发送,空格,转换为%,中文/其他字符,直接把字符串用base64加密。%xx表示xx为16进制数。
(2)post把提交数据放置在http包的包体中
2、数据长度限制
(1)受浏览器的限制,IE对url长度限制是2083字节,其他浏览器,理论上没限制,限制取决于操作系统。
(2)post理论上没有数据限制,限制取决于服务器的处理能力。
(3)iis6.0,微软出于安全考虑,加大了限制。asp post数据量最大为200kB,每个表单域限制是100kB。默认上传文件的最大为4MB。默认最大请求头是16KB。
3、安全性
(1)get以明文方式提交数据,account和password明文出现在url上,登录页面有可能被浏览器缓存,其他人查看到浏览器的历史记录,可以轻易拿到你的account和pw,还可能跨站攻击。
四大方法简介
DELETE /uri/xxx 删除
PUT /uri/xxx 更新或创建
GET /uri/xxx 查看
GET操作是安全的
所谓安全是指不管进行多少次操作,资源的状态都不会改变。比如我用GET浏览文章,不管浏览多少次,那篇文章还在那,没有变化。当然,你可能说每浏览一次文章,文章的浏览数就加一,这不也改变了资源的状态么?这并不矛盾,因为这个改变不是GET操作引起的,而是用户自己设定的服务端逻辑造成的。
PUT,DELETE操作是幂等的
所谓幂等是指不管进行多少次操作,结果都一样。比如我用PUT修改一篇文章,然后在做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。顺便说一句,因为GET操作是安全的,所以它自然也是幂等的。
POST操作既不是安全的,也不是幂等的
比如常见的POST重复加载问题:当我们多次发出同样的POST请求后,其结果是创建出了若干的资源。
安全和幂等的意义在于:当操作没有达到预期的目标时,我们可以不停的重试,而不会对资源产生副作用。从这个意义上说,POST操作往往是有害的,但很多时候我们还是不得不使用它。
还有一点需要注意的就是,创建操作可以使用POST,也可以使用PUT,区别在于POST 是作用在一个集合资源之上的(/uri),而PUT操作是作用在一个具体资源之上的(/uri/xxx),再通俗点说,如果URL可以在客户端确定,那么就使用PUT,如果是在服务端确定,那么就使用POST,比如说很多资源使用数据库自增主键作为标识信息,而创建的资源的标识信息到底是什么只能由服务端提供,这个时候就必须使用POST。
PUT vs POST
Both PUT and POST can be used for creating.
You have to ask "what are you performing the action to?" to distinguish what you should be using. If you want to use POST then you would do that to a list of questions. If you want to use PUT then you would do that to a particular question.
Great both can be used, so which one should I use in my RESTful design:
You do not need to support both PUT and POST.
Which is used is left up to you. But just remember to use the right one depending on what object you are referencing in the request.
PUT implies putting a resource - completely replacing whatever is available at the given URL with a different thing. By definition, a PUT is idempotent. Do it as many times as you like, and the result is the same. x=5 is idempotent. You can PUT a resource whether it previously exists, or not (eg, to Create, or to Update)!
POST updates a resource, adds a subsidiary resource, or causes a change. A POST is not idempotent, in the way that x++ is not idempotent.
There seems to always be some confusion as to when to use the HTTP POST versus the HTTP PUT method for REST services. Most developers will try to associate CRUD operations directly to HTTP methods. I will argue that this is not correct and one can not simply associate the CRUD concepts to the HTTP methods. That is:
Create => HTTP PUT
Retrieve => HTTP GET
Update => HTTP POST
Delete => HTTP DELETE
It is true that the R(etrieve) and D(elete) of the CRUD operations can be mapped directly to the HTTP methods GET and DELETE respectively. However, the confusion lies in the C(reate) and U(update) operations. In some cases, one can use the PUT for a create while in other cases a POST will be required. The ambiguity lies in the definition of an HTTP PUT method versus an HTTP POST method.
According to the HTTP 1.1 specifications the GET, HEAD, DELETE, and PUT methods must be idempotent, and the POST method is not idempotent. That is to say that an operation is idempotent if it can be performed on a resource once or many times and always return the same state of that resource. Whereas a non idempotent operation can return a modified state of the resource from one request to another. Hence, in a non idempotent operation, there is no guarantee that one will receive the same state of a resource.
Based on the above idempotent definition, my take on using the HTTP PUT method versus using the HTTP POST method for REST services is:
Use the HTTP PUT method when:
The client includes all aspect of the resource including the unique identifier to uniquely identify the resource. Example: creating a new employee.
The client provides all the information for a resource to be able to modify that resource.This implies that the server side does not update any aspect of the resource (such as an update date).
In both cases, these operations can be performed multiple times with the same results. That is the resource will not be changed by requesting the operation more than once. Hence, a true idempotent operation.
Use the HTTP POST method when:
The server will provide some information concerning the newly created resource. For example, take a logging system. A new entry in the log will most likely have a numbering scheme which is determined on the server side. Upon creating a new log entry, the new sequence number will be determined by the server and not by the client.
On a modification of a resource, the server will provide such information as a resource state or an update date. Again in this case not all information was provided by the client and the resource will be changing from one modification request to the next. Hence a non idempotent operation.
Conclusion
Do not directly correlate and map CRUD operations to HTTP methods for REST services. The use of an HTTP PUT method versus an HTTP POST method should be based on the idempotent aspect of that operation. That is, if the operation is idempotent, then use the HTTP PUT method. If the operation is non idempotent, then use the HTTP POST method.
一些注意事项
Do you name your URL objects you create explicitly, or let the server decide? If you name them then use PUT. If you let the server decide then use POST.
PUT is idempotent, so if you PUT an object twice, it has no effect. This is a nice property, so I would use PUT when possible.
You can update or create a resource with PUT with the same object URL.
With POST you can have 2 requests coming in at the same time making modifications to a URL, and they may update different parts of the object.
如何使用put、delete方法
1、在浏览器里实现
HTML forms (up to HTML version 4 and XHTML 1) only support GET and POST as HTTP request methods. A workaround for this is to tunnel other methods through POST by using a hidden form field which is read by the server and the request dispatched accordingly.
However, for the vast majority of RESTful web services GET, POST, PUT and DELETE should be sufficient. All these methods are supported by the implementations of XMLHttpRequest in all the major web browsers (IE, Firefox, Opera).
XMLHttpRequest supports every method, including CHICKEN, though some method names are matched against case-insensitively (methods are case-sensitive per HTTP) and some method names are not supported at all for security reasons.
因此,这种支持还需要浏览器的支持,着重于对'XMLHttpRequest'支持是否友好,在ajax中,是可以显示地声明用何种方法。在
jQuery.ajax()中,就可以做如下实现:
$.ajax({
url: 'script.php',
type: 'PUT',
success: function(response) {
//...
}
});
param 'type'就是需要设置的地方。
2、第三方脚本工具实现
在Perl的cpan上,通过查询'rest'的关键字就会找到不少用于校验相关功能模块及脚本,像'REST::Client'、'REST::Consumer'、' REST-Resource-client'等。
参考来源:
put-vs-post-in-rest
Hypertext Transfer Protocol -- HTTP/1.1
rest-http-post-vs-http-put