RESTful编程到底是什么?
当前回答
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通常是如何实现的,而不是它的真正含义。我修改了答案,以更好地代表真正的含义。)
其他回答
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通常是如何实现的,而不是它的真正含义。我修改了答案,以更好地代表真正的含义。)
这在任何地方都很少被提及,但Richardson的成熟度模型是实际判断Restful是API的最佳方法之一。更多信息请点击此处:
理查德森成熟度模型
RESTful(代表性状态转移)API编程是通过以下5个基本的软件架构风格原则,以任何编程语言编写web应用程序:
资源(数据、信息)。唯一的全局标识符(所有资源都由URI标识)。统一接口-使用简单标准接口(HTTP)。表示-所有通信都是通过表示(例如XML/JSON)完成的无状态(每个请求都是在完全隔离的情况下发生的,这样更容易缓存和负载平衡),
换句话说,您正在通过HTTP编写简单的点对点网络应用程序,该应用程序通过实现RESTful架构使用GET、POST、PUT或DELETE等动词,该架构提出了每个“资源”公开的接口的标准化。以一种简单有效的方式(高度成功、经过验证和分布式架构)使用web的当前特性并不重要。它是SOAP、CORBA和RPC等更复杂机制的替代方案。
RESTful编程符合Web体系结构设计,如果实现得当,它允许您充分利用可扩展的Web基础设施。
REST是一种编写分布式应用程序的架构模式和风格。它不是狭义的编程风格。
说你使用REST风格类似于说你建造了一个特定风格的房子:例如都铎风格或维多利亚风格。REST作为一种软件风格,都铎或维多利亚风格作为一种家居风格,都可以通过构成它们的质量和约束来定义。例如,REST必须具有客户端-服务器分离,其中消息是自我描述的。都铎风格的房屋有重叠的山墙和屋顶,这些山墙和前面的山墙陡峭倾斜。您可以阅读Roy的论文,以了解更多关于构成REST的约束和质量的信息。
与家庭风格不同的REST在持续和实际应用中遇到了困难。这可能是故意的。将其实际实现留给设计者。所以你可以自由地做你想做的事情,只要你满足论文中提出的约束条件,你就可以创建REST系统。
奖金:
整个web都基于REST(或REST基于web)。因此,作为一名web开发人员,您可能需要意识到这一点,尽管编写好的web应用程序并不必要。
本质上没有“RESTful编程”这样的概念。它最好被称为RESTful范式,甚至更好的RESTful架构。它不是一种编程语言。这是一个范例。
来自维基百科:
在计算中,表示状态转移(REST)是一种用于web开发的体系结构风格。
推荐文章
- ReferenceError: description没有定义NodeJs
- REST API - dto还是不是?
- OData和REST web服务的区别
- Symfony 2.x中的所有东西都应该捆绑吗?
- 用Spring我可以做一个可选的路径变量吗?
- 什么是HTTP“主机”报头?
- 用Python构建最小的插件架构
- 哪个HTTP状态代码表示“尚未准备好,稍后再试”?
- Django REST框架:向ModelSerializer添加额外字段
- 如何阻止恶意代码欺骗“Origin”报头来利用CORS?
- 模式、表和数据库之间的区别是什么?
- 为什么说“HTTP是无状态协议”?
- 我需要HTTP GET请求的内容类型报头吗?
- REST和RPC之间的Web服务差异
- 单页应用:优点和缺点