RESTful编程到底是什么?
当前回答
如果我不得不将关于REST的原始论文缩减为短短的3句话,我认为以下内容抓住了它的精髓:
通过URL请求资源。协议仅限于使用URL进行通信的内容。元数据作为名称-值对(发布数据和查询字符串参数)传递。
之后,很容易陷入关于适应、编码约定和最佳实践的争论。
有趣的是,本文中没有提到HTTPPOST、GET、DELETE或PUT操作。这一定是后来有人对“统一界面”的“最佳实践”的解释。
当涉及到web服务时,我们似乎需要一些方法来区分WSDL和基于SOAP的体系结构,这会给接口增加相当大的开销和不必要的复杂性。它们还需要额外的框架和开发人员工具才能实现。我不确定REST是否是区分常识接口和过度工程化接口(如WSDL和SOAP)的最佳术语。但我们需要一些东西。
其他回答
一种称为REST(RepresentationalStateTransfer)的体系结构风格主张web应用程序应该像最初设想的那样使用HTTP。查找应使用GET请求。PUT、POST和DELETE请求应分别用于变异、创建和删除。
REST支持者倾向于使用URL,例如
http://myserver.com/catalog/item/1729
但REST架构不需要这些“漂亮的URL”。带有参数的GET请求
http://myserver.com/catalog?item=1729
完全是RESTful的。
请记住,GET请求不应用于更新信息。例如,向购物车添加项目的GET请求
http://myserver.com/addToCart?cart=314159&item=1729
这是不合适的。GET请求应该是幂等的。也就是说,发出两次请求与发出一次请求应该没有区别。这就是请求可缓存的原因。一个“添加到购物车”请求不是幂等的,发出两次请求会向购物车添加两个项目副本。POST请求显然适合于这种情况。因此,即使是RESTful web应用程序也需要共享POST请求。
这摘自大卫·M·Geary的优秀著作《核心JavaServer面孔》。
如果我没有直接回答这个问题,我很抱歉,但通过更详细的例子更容易理解这一切。由于所有的抽象和术语,字段化并不容易理解。
这里有一个很好的例子:
解释REST和超文本:垃圾邮件清理机器人Spam-E
更棒的是,这里有一个简单的例子(powerpoint更全面,但你可以在html版本中获得大部分内容):
http://www.xfront.com/REST.ppt或http://www.xfront.com/REST.html
看完这些例子后,我明白了Ken为什么说REST是超文本驱动的。但我实际上并不确定他是对的,因为/user/123是指向资源的URI,我不清楚它是否是非RESTful的,因为客户端知道它是“带外”的
xfront文档解释了REST和SOAP之间的区别,这也非常有用。当Fielding说:“这是RPC。它尖叫RPC。”时,很明显RPC不是RESTful的,所以了解这一点的确切原因很有用。(SOAP是RPC的一种类型。)
REST是web的基础架构原则。web的惊人之处在于,客户端(浏览器)和服务器可以以复杂的方式交互,而客户端事先不知道服务器及其托管的资源。关键的限制是服务器和客户端都必须对所使用的媒体达成一致,在web的情况下,媒体是HTML。
遵循REST原则的API不要求客户端了解API的结构。相反,服务器需要提供客户端与服务交互所需的任何信息。HTML表单就是这样的一个例子:服务器指定资源的位置和所需的字段。浏览器事先不知道在哪里提交信息,也不知道要提交什么信息。这两种形式的信息完全由服务器提供。(这一原则被称为HATEOAS:作为应用程序状态引擎的超媒体。)
那么,这如何适用于HTTP,如何在实践中实现呢?HTTP以动词和资源为导向。主流用法中的两个动词是GET和POST,我想每个人都会认识到。然而,HTTP标准定义了其他几个,如PUT和DELETE。然后根据服务器提供的指令将这些动词应用于资源。
例如,假设我们有一个由web服务管理的用户数据库。我们的服务使用一个基于JSON的自定义超媒体,为此我们分配了mimetype application/JSON+userdb(也可能有application/xml+userdb和application/whatever+userdb-可能支持许多媒体类型)。客户机和服务器都经过编程,可以理解这种格式,但他们对彼此一无所知。正如罗伊·菲尔丁指出的:
REST API应该在定义用于表示资源和驱动的媒体类型应用程序状态,或定义扩展关系名称和/或现有标准媒体类型的超文本标记。
对基本资源/的请求可能会返回如下内容:
要求
GET /
Accept: application/json+userdb
回答
200 OK
Content-Type: application/json+userdb
{
"version": "1.0",
"links": [
{
"href": "/user",
"rel": "list",
"method": "GET"
},
{
"href": "/user",
"rel": "create",
"method": "POST"
}
]
}
我们从媒体的描述中知道,我们可以从“链接”部分找到有关相关资源的信息。这称为超媒体控件。在这种情况下,我们可以从这样一个部分看出,通过对/user发出另一个请求,我们可以找到一个用户列表:
要求
GET /user
Accept: application/json+userdb
回答
200 OK
Content-Type: application/json+userdb
{
"users": [
{
"id": 1,
"name": "Emil",
"country: "Sweden",
"links": [
{
"href": "/user/1",
"rel": "self",
"method": "GET"
},
{
"href": "/user/1",
"rel": "edit",
"method": "PUT"
},
{
"href": "/user/1",
"rel": "delete",
"method": "DELETE"
}
]
},
{
"id": 2,
"name": "Adam",
"country: "Scotland",
"links": [
{
"href": "/user/2",
"rel": "self",
"method": "GET"
},
{
"href": "/user/2",
"rel": "edit",
"method": "PUT"
},
{
"href": "/user/2",
"rel": "delete",
"method": "DELETE"
}
]
}
],
"links": [
{
"href": "/user",
"rel": "create",
"method": "POST"
}
]
}
从这一反应中我们可以看出很多。例如,我们现在知道可以通过向/user发帖来创建新用户:
要求
POST /user
Accept: application/json+userdb
Content-Type: application/json+userdb
{
"name": "Karl",
"country": "Austria"
}
回答
201 Created
Content-Type: application/json+userdb
{
"user": {
"id": 3,
"name": "Karl",
"country": "Austria",
"links": [
{
"href": "/user/3",
"rel": "self",
"method": "GET"
},
{
"href": "/user/3",
"rel": "edit",
"method": "PUT"
},
{
"href": "/user/3",
"rel": "delete",
"method": "DELETE"
}
]
},
"links": {
"href": "/user",
"rel": "list",
"method": "GET"
}
}
我们还知道,我们可以更改现有数据:
要求
PUT /user/1
Accept: application/json+userdb
Content-Type: application/json+userdb
{
"name": "Emil",
"country": "Bhutan"
}
回答
200 OK
Content-Type: application/json+userdb
{
"user": {
"id": 1,
"name": "Emil",
"country": "Bhutan",
"links": [
{
"href": "/user/1",
"rel": "self",
"method": "GET"
},
{
"href": "/user/1",
"rel": "edit",
"method": "PUT"
},
{
"href": "/user/1",
"rel": "delete",
"method": "DELETE"
}
]
},
"links": {
"href": "/user",
"rel": "list",
"method": "GET"
}
}
请注意,我们使用不同的HTTP动词(GET、PUT、POST、DELETE等)来操纵这些资源,并且我们假设客户端的唯一知识是我们的媒体定义。
进一步阅读:
这一页上有很多更好的答案。我如何向妻子解释REST。我如何向妻子解释REST。马丁·福勒的思想PayPal的API具有超媒体控制
(这个答案因为没有抓住重点而受到了相当多的批评。在大多数情况下,这是一个公平的批评。我最初描述的内容更符合几年前我第一次写这篇文章时REST通常是如何实现的,而不是它的真正含义。我修改了答案,以更好地代表真正的含义。)
本质上没有“RESTful编程”这样的概念。它最好被称为RESTful范式,甚至更好的RESTful架构。它不是一种编程语言。这是一个范例。
来自维基百科:
在计算中,表示状态转移(REST)是一种用于web开发的体系结构风格。
REST代表代表性状态转移。
它依赖于一个无状态的、客户端-服务器的、可缓存的通信协议——实际上在所有情况下都使用HTTP协议。
REST通常用于移动应用程序、社交网络网站、mashup工具和自动化业务流程。REST风格强调通过有限数量的操作(动词)来增强客户端和服务之间的交互。通过将资源(名词)分配给它们自己独特的通用资源指示符(URI)来提供灵活性。
休息介绍
推荐文章
- 模式、表和数据库之间的区别是什么?
- 为什么说“HTTP是无状态协议”?
- 我需要HTTP GET请求的内容类型报头吗?
- REST和RPC之间的Web服务差异
- 单页应用:优点和缺点
- 如何让Chrome允许混合内容?
- 正确的方式删除cookies服务器端
- REST DELETE真的是幂等的吗?
- 如何用node.js实现一个安全的REST API
- 如何在Node.js内进行远程REST调用?旋度吗?
- 了解Chrome网络日志“停滞”状态
- 用户代理字符串可以有多大?
- 什么是接受* HTTP报头q=0.5 ?
- HTTP状态码200(缓存)和状态码304之间有什么区别?
- Rails new vs create