RESTful编程究竟是什么?
RESTful编程究竟是什么?
一个 建筑风格 叫 REST(代表性国家转移) 主张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请求份额。
这取自优秀的书 核心JavaServer面临 David M. Geary的书。
休息 是网络的基本架构原则。关于Web的惊人之处在于,客户端(浏览器)和服务器可以以复杂的方式进行交互,而客户端无需事先了解服务器及其承载的资源。关键的限制是服务器和客户端都必须同意 媒体 使用,在网络的情况下是 HTML。
符合原则的API 休息 不要求客户端知道有关API结构的任何信息。相反,服务器需要提供客户端与服务交互所需的任何信息。一个 HTML表单 就是一个例子:服务器指定资源的位置和必填字段。 浏览器事先不知道提交信息的位置,并且事先不知道要提交哪些信息。两种形式的信息完全由服务器提供。 (这个原则被称为 HATEOAS:超媒体作为应用程序状态的引擎。)
那么,这是如何适用的 HTTP,它如何在实践中实施? HTTP围绕动词和资源。主流使用的两个动词是GET和POST,我想每个人都会认识到。但是,HTTP标准定义了其他几个,如PUT和DELETE。然后根据服务器提供的指令将这些动词应用于资源。
例如,假设我们有一个由Web服务管理的用户数据库。我们的服务使用基于JSON的自定义超媒体,我们为其分配mimetype 应用/ JSON + USERDB (可能还有一个 应用/ XML + USERDB 和 应用程序/无论+ 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"
}
]
}
我们可以从这个回复中说出很多。例如,我们现在知道我们可以通过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时首先写下这个,而不是它的真实含义。我修改了答案以更好地代表真正的意义。)
RESTful编程是关于:
Create
, Retrieve
, Update
, Delete
变 POST
, GET
, PUT
,和 DELETE
。但REST不仅限于HTTP,它只是目前最常用的传输方式。 就REST的后果和整体有效性而言,最后一个可能是最重要的。总体而言,大多数RESTful讨论似乎都集中在HTTP及其在浏览器中的使用,而不是。我理解R.Fielding在描述导致HTTP的架构和决策时创造了这个术语。他的论文更多地是关于资源的体系结构和缓存能力而不是HTTP。
如果您真的对RESTful架构及其工作原理感兴趣,请阅读 他的论文 几次阅读 整件事 不只是第5章!接下来看看 为什么DNS工作。了解DNS的层次结构以及推荐的工作原理。然后阅读并考虑DNS缓存的工作原理。最后,阅读HTTP规范(RFC2616 和 RFC3040 特别是)并考虑缓存如何以及为什么以它的方式工作。最终,它只会点击。对我来说最后的启示是当我看到DNS和HTTP之间的相似之处时。在此之后,了解SOA和消息传递接口可扩展的原因开始单击。
我认为这是理解RESTful和REST的体系结构重要性和性能影响的最重要技巧 没有共享 架构是为了避免陷入技术和实现细节。专注于谁拥有资源,谁负责创建/维护它们等等。然后考虑表示,协议和技术。
这可能是它的样子。
创建具有三个属性的用户:
POST /user
fname=John&lname=Doe&age=25
服务器响应:
200 OK
Location: /user/123
将来,您可以检索用户信息:
GET /user/123
服务器响应:
200 OK
<fname>John</fname><lname>Doe</lname><age>25</age>
修改记录(lname
和 age
将保持不变):
PATCH /user/123
fname=Johnny
更新记录(因此 lname
和 age
将为NULL):
PUT /user/123
fname=Johnny
一本关于REST的好书是 实践中的REST。
必读是 代表性国家转移(REST) 和 REST API必须是超文本驱动的
参见Martin Fowlers的文章 理查森成熟度模型 (RMM)有关RESTful服务的解释。
要成为RESTful,服务需要满足 超媒体作为应用状态的引擎。 (HATEOAS),也就是说,它需要在RMM中达到3级, 阅读文章 详情或 来自qcon谈话的幻灯片。
HATEOAS约束是首字母缩写词 用于超媒体作为引擎 申请国。这个原则是 REST之间的关键区别 和大多数其他形式的客户端服务器 系统。
...
RESTful应用程序的客户端需要 只知道要访问的单个固定URL 它。所有未来的行动都应该是 可动态发现 超媒体链接包含在 表示资源 从该URL返回。 标准化媒体类型也是 任何人都应该理解 可能使用RESTful API的客户端。 (维基百科,自由的百科全书)
用于Web框架的REST Litmus测试 是一个类似的Web框架成熟度测试。
接近纯REST:学会爱HATEOAS 是一个很好的链接集合。
REST与公共云的SOAP 讨论了REST使用的当前级别。
REST和版本控制 讨论了可扩展性,版本控制,可演化性等。 通过可修改性
什么是REST?
REST代表Representational State Transfer。 (有时候 拼写为“ReST”。)它依赖于无状态的客户端服务器,可缓存 通信协议 - 实际上在所有情况下都是HTTP 使用协议。
REST是一种用于设计网络应用程序的架构风格。 这个想法是,而不是使用CORBA之类的复杂机制, 用于在机器之间连接的RPC或SOAP,用于制作简单的HTTP 机器之间的通话。
在许多方面,可以查看基于HTTP的万维网本身 作为基于REST的架构。 RESTful应用程序使用HTTP请求 发布数据(创建和/或更新),读取数据(例如,进行查询), 并删除数据。因此,REST对所有四个CRUD使用HTTP (创建/读取/更新/删除)操作。
REST是RPC(Remote)等机制的轻量级替代品 过程调用)和Web服务(SOAP,WSDL等)。稍后,我们会 看看REST有多简单。
尽管很简单,但REST功能齐全;基本上就是这样 您无法在Web服务中执行任何无法使用RESTful执行的操作 建筑。 REST不是“标准”。永远不会有W3C 例如,推荐REST用于REST。虽然有REST 编程框架,使用REST非常简单,你可以 通常使用标准库功能“滚动你自己” Perl,Java或C#。
当我试图找到休息的简单真实含义时,我发现了最好的参考之一。
REST使用各种HTTP方法(主要是GET / PUT / DELETE)来操作数据。
而不是使用特定的URL来删除方法(比方说, /user/123/delete
),你会发送一个DELETE请求 /user/[id]
用于编辑用户的URL,用于检索发送GET请求的用户的信息 /user/[id]
例如,相反,一组URL可能看起来像下面的一些..
GET /delete_user.x?id=123
GET /user/delete
GET /new_user.x
GET /user/new
GET /user?id=1
GET /user/id/1
你使用HTTP“动词”并拥有..
GET /user/2
DELETE /user/2
PUT /user
它是您的系统架构适合的编程 REST风格 罗伊菲尔丁在2004年制定 他的论文。由于这是描述网络的架构风格(或多或少),很多人对此感兴趣。
奖励答案:不会。除非您正在研究软件架构作为学术或设计Web服务,否则没有理由听到这个术语。
我想说RESTful编程将是关于创建遵循REST架构风格的系统(API)。
我找到了M. Elkstein博士关于REST的精彩,简短且易于理解的教程,并引用了大部分内容可以回答你的问题:
REST是一个 建筑风格 用于设计网络应用程序。 这个想法是,而不是使用CORBA之类的复杂机制, 用于在机器之间连接的RPC或SOAP,用于制作简单的HTTP 机器之间的通话。
- 在许多方面,基于HTTP的万维网本身可以被视为基于REST的架构。
RESTful应用程序使用HTTP请求发布数据(创建和/或 更新),读取数据(例如,进行查询)和删除数据。因此,REST 对所有四个CRUD(创建/读取/更新/删除)操作使用HTTP。
我认为你不应该因为没有听到Stack Overflow之外的REST而感到愚蠢......,我会处于同样的境地!关于这个其他SO问题的答案 为什么REST现在变大了 可以缓解一些感受。
如果我没有直接回答这个问题,我会道歉,但通过更详细的例子更容易理解这一切。由于所有的抽象和术语,Fielding不容易理解。
这里有一个相当不错的例子:
更好的是,这里有一个简单示例的清晰解释(powerpoint更全面,但你可以在html版本中获得大部分内容):
http://www.xfront.com/REST.ppt 要么 http://www.xfront.com/REST.html
阅读完示例后,我可以看出为什么Ken说REST是超文本驱动的。我不确定他是对的,因为/ user / 123是一个指向资源的URI,并且我不清楚它是不是因为客户端“带外”知道它是不可靠的。
该xfront文档解释了REST和SOAP之间的区别,这也非常有用。菲尔丁说,“那是RPC。它尖叫RPC。“很明显,RPC不是RESTful,因此查看确切原因很有用。(SOAP是一种RPC。)