4102

RESTful 编程到底是什么?

4

35 回答 35

2970

REST是 Web 的底层架构原则。Web 的惊人之处在于,客户端(浏览器)和服务器可以以复杂的方式进行交互,而客户端无需事先了解服务器及其托管的资源。关键约束是服务器和客户端都必须就使用的媒体达成一致,在 Web 的情况下是HTML

遵循REST原则的 API不需要客户端了解 API 的结构。相反,服务器需要提供客户端与服务交互所需的任何信息。HTML 表单就是一个例子:服务器指定资源的位置和必填字段。浏览器事先不知道在哪里提交信息,也不事先知道要提交什么信息。两种形式的信息都完全由服务器提供。(这个原理被称为HATEOAS : Hypermedia As The Engine Of Application State。)

那么,这如何应用于HTTP,以及如何在实践中实现呢?HTTP 以动词和资源为导向。主流用法中的两个动词是GETand POST,我想大家都会认识的。但是,HTTP 标准定义了其他几个标准,例如PUTDELETE。然后根据服务器提供的指令将这些动词应用于资源。

例如,假设我们有一个由 Web 服务管理的用户数据库。我们的服务使用基于 JSON 的自定义超媒体,我们为其分配 mimetype application/json+userdb(也可能有一个application/xml+userdbapplication/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"
        }
    ]
}

我们可以从这个回应中看出很多。例如,我们现在知道我们可以通过POSTing 来创建一个新用户/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 动词(GETPUTPOSTDELETE)来操作这些资源,并且我们假设客户端的唯一知识是我们的媒体定义。

进一步阅读:

(这个答案因为没有抓住重点而受到相当多的批评。在大多数情况下,这是一个公平的批评。我最初描述的内容更符合几年前我通常如何实现 REST首先写这个,而不是它的真正含义。我已经修改了答案以更好地代表真正的含义。)

于 2009-03-22T14:53:10.937 回答
803

一种称为REST(Representational State Transfer)的架构风格主张 Web 应用程序应该使用最初设想的 HTTP 。查找应该使用请求。, , 和requests应分别用于突变创建删除GETPUTPOSTDELETE

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 请求份额。

这取自 David M. Geary 的优秀书籍Core JavaServer faces book。

于 2015-04-15T11:26:17.950 回答
545

RESTful 编程是关于:

  • 由持久标识符标识的资源:如今,URI 是无处不在的标识符选择
  • 使用一组通用动词操作资源:HTTP 方法是常见的情况——古老的Create, Retrieve, Update,Delete变成POST, GET,PUTDELETE. 但 REST 不限于 HTTP,它只是目前最常用的传输方式。
  • 为资源检索的实际表示取决于请求而不是标识符:使用 Accept 标头来控制您是否需要 XML、HTTP 甚至是表示资源的 Java 对象
  • 维护对象中的状态并在表示中表示状态
  • 在资源的表示中表示资源之间的关系:对象之间的链接直接嵌入在表示中
  • 资源表示描述了如何使用表示以及在什么情况下应该以一致的方式丢弃/重新获取它: HTTP Cache-Control 标头的使用

就 REST 的后果和整体有效性而言,最后一个可能是最重要的。总体而言,大多数 RESTful 讨论似乎都集中在 HTTP 及其在浏览器中的使用以及其他方面。我知道 R. Fielding 在描述导致 HTTP 的架构和决策时创造了这个术语。他的论文更多地是关于资源的架构和缓存能力,而不是关于 HTTP。

如果你真的对什么是 RESTful 架构以及它的工作原理感兴趣,请阅读他的论文几遍,并阅读整个内容,而不仅仅是第 5 章!接下来看看DNS 工作的原因。阅读有关 DNS 的分层组织以及引荐的工作原理。然后阅读并考虑 DNS 缓存的工作原理。最后,阅读 HTTP 规范(特别是RFC2616RFC3040)并考虑缓存如何以及为什么会以这种方式工作。最终,它只会点击。对我来说,最后的启示是当我看到 DNS 和 HTTP 之间的相似性时。在此之后,开始点击了解 SOA 和消息传递接口为何具有可扩展性。

我认为理解 RESTful 和Shared Nothing架构的架构重要性和性能影响的最重要技巧是避免陷入技术和实现细节上。关注谁拥有资源,谁负责创建/维护资源等。然后考虑表示、协议和技术。

于 2009-03-22T19:37:57.087 回答
412

这可能是它的样子。

创建具有三个属性的用户:

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
于 2009-07-04T05:47:13.313 回答
183

一本关于 REST 的好书是REST in Practice

必须阅读的是具象状态传输 (REST),并且REST API 必须是超文本驱动的

有关什么是 RESTful 服务的解释,请参阅 Martin Fowlers 文章Richardson 成熟度模型(RMM)。

理查森成熟度模型

要成为 RESTful 服务,需要将超媒体作为应用程序状态的引擎。(HATEOAS),也就是需要在RMM中达到3级,详细阅读文章或者qcon talk中的slides

HATEOAS 约束是 Hypermedia as the Engine of Application State 的首字母缩写。此原则是 REST 与大多数其他形式的客户端服务器系统之间的关键区别。

...

RESTful 应用程序的客户端只需要知道一个固定的 URL 即可访问它。所有未来的动作都应该可以从包含在从该 URL 返回的资源表示中的超媒体链接中动态发现。任何可能使用 RESTful API 的客户端也应该能够理解标准化的媒体类型。(维基百科,自由的百科全书)

Web 框架的REST Litmus 测试是针对 Web 框架的类似成熟度测试。

接近纯 REST:学会爱上 HATEOAS是一个很好的链接集合。

公共云的 REST 与 SOAP讨论了 REST 的当前使用水平。

REST 和版本控制通过可修改性讨论可扩展性、版本控制、可演化性等

于 2010-10-16T21:24:42.327 回答
138

什么是 REST?

REST 代表具象状态转移。(有时拼写为“ReST”。)它依赖于无状态、客户端-服务器、可缓存的通信协议——几乎在所有情况下都使用 HTTP 协议。

REST 是一种用于设计网络应用程序的架构风格。这个想法是,不是使用复杂的机制,如 CORBA、RPC 或 SOAP 来连接机器,而是使用简单的 HTTP 在机器之间进行调用。

在许多方面,基于 HTTP 的万维网本身可以被视为基于 REST 的架构。RESTful 应用程序使用 HTTP 请求来发布数据(创建和/或更新)、读取数据(例如,进行查询)和删除数据。因此,REST 将 HTTP 用于所有四个 CRUD(创建/读取/更新/删除)操作。

REST 是 RPC(远程过程调用)和 Web 服务(SOAP、WSDL 等)等机制的轻量级替代方案。稍后,我们将看到 REST 是多么简单。

尽管很简单,但 REST 功能齐全;在 Web 服务中,基本上没有什么是 RESTful 架构无法完成的。REST 不是“标准”。例如,永远不会有针对 REST 的 W3C 推荐。尽管有 REST 编程框架,但使用 REST 非常简单,您通常可以使用 Perl、Java 或 C# 等语言的标准库功能“自行开发”。

当我试图找到休息的简单真正含义时,我找到了最好的参考资料之一。

http://rest.elkstein.org/

于 2012-11-18T20:46:20.347 回答
93

REST 使用各种 HTTP 方法(主要是 GET/PUT/DELETE)来操作数据。

与其使用特定的 URL 来删除方法(例如/user/123/delete/user/[id]/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
于 2009-03-22T15:20:09.483 回答
70

这是一种编程,您的系统架构符合Roy Fielding 在他的论文中提出的REST 风格。由于这是描述网络的架构风格(或多或少),所以很多人都对它感兴趣。

奖励答案:不。除非您正在研究软件架构作为学术或设计 Web 服务,否则真的没有理由听说过这个术语。

于 2009-03-22T14:53:56.787 回答
49

我会说 RESTful 编程是关于创建遵循 REST 架构风格的系统 (API)。

我发现 M. Elkstein 博士撰写的关于 REST 的精彩、简短且易于理解的教程,并引用了大部分可以回答您的问题的基本部分:

学习 REST:教程

REST 是一种用于设计网络应用程序的架构风格。这个想法是,不是使用复杂的机制,如 CORBA、RPC 或 SOAP 来连接机器,而是使用简单的 HTTP 在机器之间进行调用。

  • 在许多方面,基于 HTTP 的万维网本身可以被视为基于 REST 的架构。

RESTful 应用程序使用 HTTP 请求来发布数据(创建和/或更新)、读取数据(例如,进行查询)和删除数据。因此,REST 将 HTTP 用于所有四个 CRUD(创建/读取/更新/删除)操作。

我认为您不应该因为在 Stack Overflow 之外没有听说过 REST 而感到愚蠢……,我也会遇到同样的情况!回答关于为什么 REST 现在变得越来越大的另一个 SO 问题可以缓解一些感受。

于 2013-07-12T16:33:02.030 回答
46

如果我没有直接回答这个问题,我深表歉意,但是通过更详细的示例更容易理解所有这些。由于所有的抽象和术语,Fielding 并不容易理解。

这里有一个相当好的例子:

解释 REST 和超文本:垃圾邮件清理机器人 Spam-E

更好的是,这里有一个简单的例子的清晰解释(powerpoint 更全面,但你可以在 html 版本中获得大部分内容):

http://www.xfront.com/REST.ppthttp://www.xfront.com/REST.html

阅读示例后,我可以理解为什么 Ken 说 REST 是超文本驱动的。不过,我实际上不确定他是否正确,因为 /user/123 是一个指向资源的 URI,而且我不清楚它是否是非 RESTful 只是因为客户端“带外”知道它。

该 xfront 文档解释了 REST 和 SOAP 之间的区别,这也很有帮助。当菲尔丁说“那是 RPC。它尖叫 RPC。 ”时,很明显 RPC 不是 RESTful,因此了解其确切原因很有用。(SOAP 是一种 RPC。)

于 2009-03-23T17:11:58.083 回答
38

什么是 REST?

REST 用官方的话说,REST 是一种架构风格,建立在某些原则之上,使用当前的“Web”基础。有 5 个 Web 基本原理可用于创建 REST 服务。

  • 原则 1:一切都是资源 在 REST 架构风格中,数据和功能被视为资源,并使用统一资源标识符 (URI) 访问,通常是 Web 上的链接。
  • 原则 2:每个资源都由唯一标识符 (URI) 标识
  • 原则 3:使用简单统一的接口
  • 原则 4:沟通由代表完成
  • 原则 5:无国籍
于 2013-07-25T09:05:19.827 回答
33

我看到一堆答案说将有关用户 123 的所有内容放在资源“/user/123”中是 RESTful。

创造这个术语的 Roy Fielding 说REST API 必须是超文本驱动的。特别是,“REST API 不得定义固定的资源名称或层次结构”。

因此,如果您的“/user/123”路径在客户端上是硬编码的,那么它并不是真正的 RESTful。很好地使用 HTTP,也许,也许不是。但不是 RESTful。它必须来自超文本。

于 2009-03-22T16:36:31.517 回答
28

答案很简单,Roy Fielding 写了一篇论文。] 1在该论文中,他定义了 REST 原则。如果一个应用程序满足所有这些原则,那么这就是一个 REST 应用程序。

创建术语 RESTful 是因为人们通过将非 REST 应用程序称为 REST 来用尽 REST 这个词。在那之后,RESTful 一词也用尽了。现在我们谈论的是 Web API 和超媒体 API,因为大多数所谓的 REST 应用程序都没有满足统一接口约束的 HATEOAS 部分。

REST 约束如下:

  1. 客户端-服务器架构

    因此它不适用于例如 PUB/SUB 套接字,它基于 REQ/REP。

  2. 无状态通信

    所以服务器不维护客户端的状态。这意味着您不能使用服务器端会话存储,并且您必须对每个请求进行身份验证。您的客户端可能通过加密连接发送基本身份验证标头。(对于大型应用程序,很难维护许多会话。)

  3. 如果可以的话,使用缓存

    因此,您不必一次又一次地处理相同的请求。

  4. 统一接口作为客户端和服务器之间的通用合同

    客户端和服务器之间的合同不由服务器维护。换句话说,客户端必须与服务的实现分离。您可以通过使用标准解决方案达到此状态,例如识别资源的 IRI (URI) 标准、交换消息的 HTTP 标准、描述正文序列化格式的标准 MIME 类型、元数据(可能是 RDF 词汇、微格式等)描述消息体不同部分的语义。要将 IRI 结构与客户端分离,您必须以超媒体格式(如 HTML、JSON-LD、HAL 等)向客户端发送超链接。因此,客户端可以使用分配给超链接的元数据(可能是链接关系,RDF 词汇)通过适当的状态转换来导航应用程序的状态机,以实现其当前目标。

    例如,当客户想要向网上商店发送订单时,它必须检查网上商店发送的响应中的超链接。通过检查链接,它找到了一个用http://schema.org/OrderAction描述的链接。客户端知道 schema.org 词汇,因此它知道通过激活此超链接将发送订单。因此它会激活超链接并发送POST https://example.com/api/v1/order带有正确正文的消息。之后,服务处理消息并以具有正确 HTTP 状态标头的结果进行响应,例如201 - created成功。要使用详细元数据注释消息,使用 RDF 格式的标准解决方案,例如带有 REST 词汇的JSON-LD,例如Hydra和特定于域的词汇,例如schema.org或任何其他链接数据词汇,如果需要,可能还有自定义应用程序特定词汇。现在这并不容易,这就是为什么大多数人使用 HAL 和其他简单格式,这些格式通常只提供 REST 词汇,但不支持链接数据。

  5. 构建分层系统以提高可扩展性

    REST 系统由分层组成。每一层都包含使用下一层组件服务的组件。因此,您可以毫不费力地添加新层和组件。

    例如,有一个包含客户端的客户端层,下面是一个包含单个服务的服务层。现在您可以在它们之间添加客户端缓存。之后,您可以添加另一个服务实例和负载均衡器,等等......客户端代码和服务代码不会改变。

  6. 按需编码以扩展客户端功能

    此约束是可选的。例如,您可以将特定媒体类型的解析器发送到客户端,等等...为了做到这一点,您可能需要客户端中的标准插件加载器系统,或者您的客户端将耦合到插件加载器解决方案.

REST 约束导致了一个高度可扩展的系统,其中客户端与服务的实现分离。所以客户端可以重复使用,就像网络上的浏览器一样。客户端和服务共享相同的标准和词汇,因此尽管客户端不知道服务的实现细节,但它们可以相互理解。这使得创建可以找到并利用 REST 服务来实现其目标的自动化客户端成为可能。从长远来看,这些客户端可以相互交流并在任务中相互信任,就像人类一样。如果我们向此类客户端添加学习模式,那么结果将是一个或多个 AI 使用机器网络而不是单个服务器园区。所以最后伯纳斯·李的梦想:语义网和人工智能将成为现实。所以在 2030 年,我们最终会被天网终结。直到那时 ... ;-)

于 2013-11-22T22:49:13.677 回答
23

RESTful (Representational state transfer) API 编程是按照以下 5 个基本的软件架构风格原则以任何编程语言编写 Web 应用程序:

  1. 资源(数据、信息)。
  2. 唯一的全局标识符(所有资源都由URI唯一标识)。
  3. 统一接口- 使用简单和标准的接口 (HTTP)。
  4. 表示 - 所有通信都是通过表示完成的(例如XML / JSON
  5. 无状态(每个请求完全隔离发生,更容易缓存和负载平衡),

换句话说,您正在通过 HTTP 编写简单的点对点网络应用程序,该应用程序通过实现 RESTful 架构来使用诸如 GET、POST、PUT 或 DELETE 之类的动词,该架构建议对每个“资源”公开的接口进行标准化。以简单有效的方式使用 Web 的当前功能(非常成功、经过验证的分布式架构),这不算什么。它是SOAPCORBARPC等更复杂机制的替代方案。

RESTful 编程符合 Web 架构设计,如果实施得当,它可以让您充分利用可扩展的 Web 基础架构。

于 2014-06-15T19:02:17.153 回答
21

这是我对 REST 的基本概述。我试图展示 RESTful 架构中每个组件背后的思想,以便更直观地理解这个概念。希望这有助于为某些人揭开 REST 的神秘面纱!

REST (Representational State Transfer) 是一种设计架构,它概述了如何设计和处理网络资源(即共享信息的节点)。一般来说,RESTful 架构使得客户端(请求机器)和服务器(响应机器)可以请求读取、写入和更新数据,而客户端不必知道服务器如何操作并且服务器可以通过它返回而无需了解有关客户端的任何信息。好的,很酷......但是我们如何在实践中做到这一点?

  • 最明显的要求是需要某种通用语言,以便服务器可以告诉客户端它试图对请求做什么并让服务器响应。

  • 但是要找到任何给定的资源,然后告诉客户端该资源所在的位置,就需要有一种通用的方式来指向资源。这就是通用资源标识符 (URI) 的用武之地;它们基本上是查找资源的唯一地址。

但是 REST 架构并没有就此结束!虽然以上满足了我们想要的基本需求,但我们还希望有一个支持大流量的架构,因为任何给定的服务器通常处理来自多个客户端的响应。因此,我们不想让服务器记住有关先前请求的信息,从而使服务器不堪重负。

  • 因此,我们强加了客户端和服务器之间的每个请求-响应对是独立的限制,这意味着服务器不必记住有关先前请求(客户端-服务器交互的先前状态)的任何信息来响应新的请求。要求。这意味着我们希望我们的交互是无状态的。

  • 为了进一步减轻我们的服务器因重做最近已经为给定客户端完成的计算而造成的压力,REST 还允许缓存。基本上,缓存意味着对提供给客户端的初始响应进行快照。如果客户端再次发出相同的请求,服务器可以向客户端提供快照,而不是重做创建初始响应所需的所有计算。然而,由于它是一个快照,如果快照没有过期——服务器提前设置了一个过期时间——并且响应自初始缓存以来已经更新(即请求将给出与缓存响应不同的答案) ,客户端将不会看到更新,直到缓存过期(或缓存被清除)并且再次从头开始呈现响应。

  • 关于 RESTful 架构,您在这里经常会遇到的最后一件事是它们是分层的。实际上,在讨论客户端和服务器之间的交互时,我们已经隐含地讨论了这个要求。基本上,这意味着我们系统中的每一层仅与相邻层交互。所以在我们的讨论中,客户端层与我们的服务器层交互(反之亦然),但可能还有其他服务器层帮助主服务器处理客户端不直接与之通信的请求。相反,服务器会根据需要传递请求。

现在,如果这一切听起来很熟悉,那就太好了。通过万维网定义通信协议的超文本传输​​协议 (HTTP) 是 RESTful 架构的抽象概念的实现(或者,如果您像我一样是 OOP 狂热者,则可以实现抽象 REST 类)。在这种 REST 实现中,客户端和服务器通过 GET、POST、PUT、DELETE 等进行交互,这些都是通用语言的一部分,并且可以使用 URL 来指向资源。

于 2017-03-31T03:12:53.680 回答
18

如果我不得不将关于 REST 的原始论文缩减为 3 个简短的句子,我认为以下内容抓住了它的精髓:

  1. 通过 URL 请求资源。
  2. 协议仅限于您可以使用 URL 进行通信的内容。
  3. 元数据作为名称-值对(发布数据和查询字符串参数)传递。

在那之后,很容易陷入关于改编、编码约定和最佳实践的争论。

有趣的是,论文中没有提到 HTTP POST、GET、DELETE 或 PUT 操作。那一定是某人后来对“统一界面”的“最佳实践”的解释。

当谈到 Web 服务时,我们似乎需要某种方法来区分基于 WSDL 和 SOAP 的架构,这会增加相当大的开销,并且可能会给接口带来不必要的复杂性。它们还需要额外的框架和开发工具才能实现。我不确定 REST 是否是区分常识接口和过度设计的接口(如 WSDL 和 SOAP)的最佳术语。但我们需要一些东西。

于 2012-02-01T17:23:09.747 回答
17

REST 是一种架构模式和编写分布式应用程序的风格。它不是狭义的编程风格。

说您使用 REST 风格类似于说您以特定风格建造房屋:例如 Tudor 或 Victorian。作为软件风格的 REST 和作为家庭风格的 Tudor 或 Victorian 都可以通过构成它们的质量和约束来定义。例如,REST 必须具有客户端服务器分离,其中消息是自描述的。都铎式风格的房屋有重叠的山墙和屋顶,这些屋顶陡峭地倾斜着面向前的山墙。您可以阅读 Roy 的论文,以了解有关构成 REST 的约束和质量的更多信息。

与家庭风格不同,REST 一直很难得到一致和实际应用。这可能是故意的。将其实际实现留给设计者。因此,只要您满足您正在创建 REST 系统的论文中规定的约束,您就可以自由地做您想做的事情。

奖金:

整个 Web 都是基于 REST(或者 REST 是基于 Web)。因此,作为一名 Web 开发人员,您可能希望了解这一点,尽管没有必要编写好的 Web 应用程序。

于 2012-02-01T21:20:21.110 回答
16

我认为 restful 的重点是将有状态分离到更高层,同时利用互联网(协议)作为无状态传输层。大多数其他方法都混淆了。

它是应对互联网时代编程根本变化的最佳实用方法。关于根本变化,Erik Meijer 在此处进行了讨论:http: //www.infoq.com/interviews/erik-meijer-programming-language-design-effects-purity#view_93197。他将其概括为五种效果,并通过将解决方案设计成编程语言来提出解决方案。该解决方案也可以在平台或系统级别实现,而与语言无关。restful 可以看作是目前实践中非常成功的解决方案之一。

使用 restful 风格,您可以在不可靠的互联网上获取和操作应用程序的状态。如果当前操作未能获得正确的当前状态,则需要零验证主体来帮助应用程序继续。如果它无法操纵状态,它通常会使用多个确认阶段来保持正确。从这个意义上说,rest 本身并不是一个完整的解决方案,它需要 web 应用程序堆栈的其他部分的功能来支持它的工作。

鉴于这种观点,其余风格并不真正与互联网或 Web 应用程序相关联。它是许多编程情况的基本解决方案。它也不简单,它只是让界面变得非常简单,并且可以很好地应对其他技术。

只是我的2c。

编辑:两个更重要的方面:

于 2014-07-03T17:30:38.460 回答
15

老问题,新的回答方式。关于这个概念有很多误解。我总是试图记住:

  1. 结构化 URL 和 Http 方法/动词不是 restful 编程的定义。
  2. JSON 不是宁静的编程
  3. RESTful 编程不适用于 API

我将宁静的编程定义为

如果应用程序以客户端理解的媒体类型提供资源(数据+状态转换控件的组合),则应用程序是宁静的

要成为一个安静的程序员,您必须尝试构建允许参与者做事的应用程序。不仅仅是暴露数据库。

只有当客户端和服务器就资源的媒体类型表示达成一致时,状态转换控制才有意义。否则就无法知道什么是控件,什么不是以及如何执行控件。IE 如果浏览器不知道<form>html 中的标签,那么您将没有任何东西可以提交到浏览器中的过渡状态。

我不想自我推销,但我在我的演讲http://techblog.bodybuilding.com/2016/01/video-what-is-restful-200.html中将这些想法扩展得非常深入。

我演讲的摘录是关于经常提到的理查森成熟度模型,我不相信这些级别,你要么是 RESTful(3 级),要么不是,但我想强调的是每个级别在通往 RESTful 的道路上为您服务

注释理查森成熟度模型

于 2016-11-30T20:05:16.560 回答
15

REST 定义了 6 个架构约束,这些约束使任何 Web 服务成为真正的 RESTful API

  1. 统一的界面
  2. 客户端服务器
  3. 无状态
  4. 可缓存
  5. 分层系统
  6. 按需编码(可选)

https://restfulapi.net/rest-architectural-constraints/

于 2017-10-02T21:23:50.023 回答
14

这是非常长的“讨论”,但至少可以说相当混乱。

海事组织:

1) 没有安静的编程,没有大联合和大量啤酒 :)

2) Representational State Transfer (REST) 是Roy Fielding 的论文中规定的一种架构风格。它有许多限制条件。如果您的服务/客户尊重这些,那么它就是 RESTful。就是这个。

您可以将约束(显着)总结为:

  • 无状态通信
  • 尊重 HTTP 规范(如果使用 HTTP)
  • 清楚地传达传输的内容格式
  • 使用超媒体作为应用程序状态的引擎

还有另一个很好的帖子很好地解释了事情。

很多答案复制/粘贴了有效信息,混合了它并增加了一些混乱。人们在这里谈论级别,关于 RESTFul URI(没有这样的东西!),应用 HTTP 方法 GET、POST、PUT ...... REST 不是关于那个或不仅仅是那个。

例如链接 - 拥有漂亮的 API 很好,但最终客户端/服务器并不真正关心您获取/发送的链接,重要的是内容。

最后,只要内容格式已知,任何 RESTful 客户端都应该能够使用任何 RESTful 服务。

于 2017-01-13T14:02:03.017 回答
12

REST === HTTP 类比是不正确的,除非您不强调它“必须”由HATEOAS驱动。

罗伊自己在这里清除了它。

除了初始 URI(书签)和适合目标受众(即,任何可能使用 API 的客户端都可以理解)的标准化媒体类型集之外,应该在没有任何先验知识的情况下输入 REST API。从那时起,所有应用程序状态转换必须由客户端选择服务器提供的选项来驱动,这些选项出现在接收到的表示中或用户对这些表示的操作暗示。转换可以由客户端对媒体类型和资源通信机制的了解来确定(或限制),这两者都可以在运行中(例如,按需编码)得到改进。

[这里的失败意味着带外信息正在推动交互而不是超文本。]

于 2016-06-03T11:35:49.920 回答
12

REST是一种基于 Web 标准和 HTTP 协议(​​2000 年引入)的架构风格。

在基于 REST 的架构中,一切都是资源(用户、订单、评论)。通过基于 HTTP 标准方法(GET、PUT、PATCH、DELETE 等)的通用接口访问资源。

在基于 REST 的架构中,您有一个 REST 服务器,它提供对资源的访问。REST 客户端可以访问和修改 REST 资源。

每个资源都应该支持 HTTP 常用操作。资源由全局 ID(通常是 URI)标识。

REST 允许资源具有不同的表示形式,例如文本、XML、JSON 等。REST 客户端可以通过 HTTP 协议(​​内容协商)请求特定的表示形式。

HTTP 方法:

PUT、GET、POST 和 DELETE 方法通常用于基于 REST 的架构中。下表给出了这些操作的说明。

  • GET 定义了对资源的读取访问权限,没有副作用。资源永远不会通过 GET 请求更改,例如,请求没有副作用(幂等)。
  • PUT 创建一个新资源。它也必须是幂等的。
  • DELETE 删除资源。操作是幂等的。它们可以重复而不会导致不同的结果。
  • POST 更新现有资源或创建新资源。
于 2017-09-15T19:47:04.400 回答
10

REST代表Representational state transfer

它依赖于无状态、客户端-服务器、可缓存的通信协议——几乎在所有情况下都使用 HTTP 协议。

REST 通常用于移动应用程序、社交网络网站、混搭工具和自动化业务流程。REST 风格强调通过有限数量的操作(动词)来增强客户端和服务之间的交互。通过为资源(名词)分配它们自己独特的通用资源指示符(URI)来提供灵活性。

休息介绍

于 2014-11-10T13:37:27.487 回答
10

谈话不仅仅是简单地交换信息。协议实际上被设计为不必发生对话。每一方都知道他们的特定工作是什么,因为它在协议中有所规定。协议允许纯粹的信息交换,代价是对可能的操作进行任何更改。另一方面,谈话允许一方询问另一方可以采取哪些进一步的行动。他们甚至可以两次问同一个问题并得到两个不同的答案,因为对方的状态可能在此期间发生了变化。讲的是 RESTful 架构。菲尔丁的论文详细说明了如果一个人想要让机器相互交流而不是简单地相互交流就必须遵循的体系结构沟通

于 2014-12-06T06:54:24.233 回答
10

本身不存在“RESTful 编程”这样的概念。最好称为 RESTful 范式,甚至更好的 RESTful 架构。它不是一种编程语言。这是一个范式。

来自维基百科

在计算中,代表性状态转移 (REST) 是一种用于 Web 开发的架构风格。

于 2016-08-24T17:57:29.140 回答
9

剩下的一点是,如果我们同意对基本操作(http 动词)使用通用语言,则可以配置基础设施以理解它们并适当优化它们,例如,通过使用缓存标头来实现缓存水平。

通过正确实施的 RESTful GET 操作,信息来自服务器的数据库、服务器的内存缓存、CDN、代理的缓存、浏览器的缓存还是浏览器的本地存储都无关紧要。可以使用禁食的、最容易获得的最新源。

说 Rest 只是从使用带有 action 参数的 GET 请求到使用可用的 http 动词的句法变化,这使它看起来没有任何好处,纯粹是装饰性的。关键是使用一种可以被链的每个部分理解和优化的语言。如果你的 GET 操作有副作用,你必须跳过所有的 HTTP 缓存,否则你会得到不一致的结果。

于 2012-02-01T23:52:15.933 回答
9

这个答案是为绝对初学者准备的,让我们了解一下当今最常用的 API 架构。

了解 Restful 编程或 Restful API。首先,您必须了解 API 是什么,在非常高级的 API 上代表应用程序编程接口,它基本上是一个软件,可以被另一个软件使用,以允许应用程序相互通信。

全球使用最广泛的 API 类型是 Web API,而应用程序在收到请求时向客户端发送数据。

在此处输入图像描述

事实上,API 不仅用于发送数据,而且并不总是与 Web 开发或 javascript 或 python 或任何编程语言或框架相关。

只要软件相对独立,API 中的应用程序实际上可以有很多不同的含义。以文件系统或 HTTP 模块为例,我们可以说它们是小软件,我们可以使用它们,我们可以使用它们的 API 与它们进行交互。例如,当我们对任何编程语言的文件系统模块使用读取文件功能时,我们实际上是在使用 file_system_reading API。或者当我们在浏览器中进行 DOM 操作时,我们并没有真正使用 JavaScript 语言本身,而是浏览器向我们公开的 DOM API,因此我们可以访问它。或者甚至另一个例子,假设我们用任何编程语言(如 Java)创建一个类,然后向它添加一些公共方法或属性,然后,这些方法将成为从该类创建的每个对象的 API,因为我们为其他软件提供了与我们的初始软件(在本例中为对象)交互的可能性。S0,API 实际上比仅仅构建 Web API 具有更广泛的含义。

现在让我们看一下构建 API 的 REST 架构。

代表 Representational State Transfer 的REST基本上是一种以逻辑方式构建 Web API 的方式,使它们易于为我们自己或他人使用。

要按照 REST 架构构建 Restful API,我们只需要遵循几个原则。1.我们需要将我们的API分离成逻辑资源。2. 然后应该使用基于资源的 URL 公开这些资源。3. 要对数据执行不同的操作,例如读取、创建或删除数据,API 应该使用正确的 HTTP 方法而不是 URL。4. 现在我们实际发送回客户端或从客户端接收到的数据通常应该使用 JSON 数据格式,是一些适用于它的格式标准。5. 最后,EST API 的另一个重要原则是它们必须是无状态的。

在此处输入图像描述

将 API 划分为逻辑资源: REST 中信息的关键抽象是资源,因此我们希望在 API 中共享的所有数据都应该划分为逻辑资源。究竟什么是资源?好吧,在 REST 的上下文中,它是一个对象或具有相关数据的事物的表示。例如,像导游、用户、地点或评论这样的应用程序就是逻辑资源的例子。所以基本上任何可以命名的信息都可以是资源。不过,只需要命名,而不是动词。 在此处输入图像描述

公开结构:现在我们需要公开,这意味着使用一些结构化的 URL 使数据可用,客户端可以向其发送请求。例如,像这样的整个地址称为 URL。并且 this / addNewTour 被称为 API Endpoint。 在此处输入图像描述

我们的 API 将有许多不同的端点,如下所示

https://www.tourguide.com/addNewTour
https://www.tourguide.com/getTour
https://www.tourguide.com/updateTour
https://www.tourguide.com/deleteTour
https://www.tourguide.com/getRoursByUser
https://www.tourguide.com/deleteToursByUser

这些 API 中的每一个都会将不同的数据发送回客户端,同时执行不同的操作。现在这些端点有一些非常错误的地方,因为它们确实不遵循第三条规则,即我们应该只使用 HTTP 方法来对数据执行操作。所以端点应该只包含我们的资源,而不是我们对它们执行的操作,因为它们很快就会成为维护的噩梦。

我们应该如何在实践中使用这些 HTTP 方法?好吧,让我们看看这些端点实际上应该如何以 /getTour 开头。所以这个 getTour 端点是为了获取关于一个旅游的数据,所以我们应该简单地将端点命名为 /tours 并在向这个端点发出获取请求时发送数据。所以换句话说,当客户端使用 GET HTTP 方法访问端点时, 在此处输入图像描述

(我们在端点或 URL 中只有资源,没有动词,因为动词现在在 HTTP 方法中,对吧?通常的做法是始终使用复数形式的资源名称,这就是我写 /tours 或 /tour 的原因。 ) 约定是调用端点 /tours 时将返回数据库中的所有旅游,但如果我们只想要一个 ID 的旅游,比如说七个,我们在另一个斜杠之后添加七个 (/tours/7)或在搜索查询 (/tours?id=7) 中,当然,它也可以是旅游的名称而不是 ID。

HTTP 方法:这里真正重要的是端点名称如何与所有人的名称完全相同。

GET: (for requesting data from the server.)

https://www.tourguide.com/tours/7
POST: (for sending data to the server.)
https://www.tourguide.com/tours
PUT/PATCH: (for updating requests for data to the server.) https://www.tourguide.com/tours/7
DELETE: (for deleting request for data to the server.)
https://www.tourguide.com/tours/7

PUT 和 PATCH 之间的区别-> 通过使用 PUT,客户端应该发送整个更新的对象,而使用 PATCH,它应该只发送已更改的对象部分。

通过使用 HTTP 方法,用户可以执行四种基本的 CRUD 操作,CRUD 代表 Create、Read、Update 和 Delete。

现在可能会出现如下情况:

在此处输入图像描述

因此,/getToursByUser 可以简单地转换为 /users/tours,因为用户号 3 的端点将类似于 /users/3/tours。

如果我们要删除特定用户的特定游览,则 URL 应类似于 /users/3/tours/7,此处用户 ID:3 和游览 ID:7。

所以真的有很多这样的组合资源的可能性。

以 JSON 格式发送数据:现在关于客户端实际接收的数据,或者服务器从客户端接收的数据,通常我们使用 JSON 数据格式。一个典型的 JSON 可能如下所示: 在此处输入图像描述 在发送 JSON 数据之前,我们通常会进行一些简单的响应格式化,对此有几个标准,但其中一个非常简单的称为 Jsend。我们只需创建一个新对象,然后向其添加状态消息,以通知客户端请求是成功、失败还是错误。然后我们将原始数据放入一个名为 Data 的新对象中。

在此处输入图像描述

像我们在这里所做的那样将数据包装到一个额外的对象中称为 Enveloping,这是一种减轻一些安全问题和其他问题的常见做法。

Restful API 应该始终是无状态的:最后,RESTful API 应该始终是无状态的,这意味着在无状态的 RESTful API 中,所有状态都在客户端而不是服务器上处理。状态只是指应用程序中可能随时间变化的一段数据。例如,某个用户是否登录或在具有多个页面的列表的页面上当前页面是什么?现在,应该在客户端处理状态这一事实意味着每个请求都必须包含在服务器上处理某个请求所需的所有信息。因此,服务器永远不必为了处理当前请求而记住先前的请求。

在此处输入图像描述

假设目前我们在第五页,我们想前进到第六页。所以我们可以有一个名为 /tours/nextPage 的简单端点并向服务器提交请求,但是服务器必须确定当前页面是什么,并基于该服务器将下一页发送到客户端。换句话说,服务器必须记住之前的请求。这正是我们希望在 RESTful API 中避免的。

除了这种情况,我们应该创建一个 /tours/page 端点并将数字 6 粘贴到它以请求第 6 页 /tours/page/6 。所以服务器不需要记住任何内容,它所要做的就是按照我们的要求发回第 6 页的数据。

无状态和相反的状态是计算机科学和一般应用中非常重要的概念

于 2020-05-21T11:09:17.257 回答
5

这一点在所有地方都很少提及,但Richardson 的成熟度模型是实际判断 Restful 是一个 API 的最佳方法之一。更多关于它的信息:

理查森的成熟度模型

于 2017-08-29T11:55:15.093 回答
4

什么是API 测试

API 测试利用编程向 API 发送调用并获得收益。它测试将被测段视为黑匣子。API 测试的目的是确认在将其协调到应用程序之前的部分的正确执行和错误处理。

REST API

REST:具象状态转移。

  • 这是测试人员执行请求和接收响应的功能安排。在 REST API 中,交互是通过 HTTP 协议进行的。
  • REST 还允许计算机之间通过网络进行通信。
  • 对于发送和接收消息,它涉及使用 HTTP 方法,并且不像 Web 服务那样需要严格的消息定义。
  • REST 消息通常接受 XML 或 JavaScript Object Notation (JSON) 形式的形式。

4 种常用 API 方法:-

  1. GET: – 它提供对资源的只读访问。
  2. POST:——用于创建或更新新资源。
  3. PUT: – 用于更新或替换现有资源或创建新资源。
  4. DELETE: – 用于删除资源。

手动测试 API 的步骤:-

要手动使用 API,我们可以使用基于浏览器的 REST API 插件。

  1. 安装 POSTMAN(Chrome) / REST(Firefox) 插件
  2. 输入 API 网址
  3. 选择 REST 方法
  4. 选择内容-标题
  5. 输入请求 JSON (POST)
  6. 点击发送
  7. 它将返回输出响应

自动化 REST API 的步骤

于 2016-08-01T06:42:41.447 回答
2

我想说理解 REST 的一个重要组成部分在于端点或映射,例如/customers/{id}/balance.

您可以将这样的端点想象为从网站(前端)到数据库/服务器(后端)的连接管道。使用它们,前端可以执行在应用程序中任何 REST 映射的相应方法中定义的后端操作。

于 2019-03-27T10:11:45.960 回答
0

编辑

阅读此处的 README,我希望您能真正获得 REST。

https://github.com/lukepuplett/surfdude-csharp/blob/master/README.md

--

那些给出链接资源示例的答案很棒,但只是图片的一半。

因此,假设您正在设计一个网站。你写一个故事,

我希望能够通过邮政编码搜索地址,以便我可以选择送货地址

然后,您将构建网站以引导用户踏上这段旅程,并尝试在工作流程中将页面链接在一起。

将他们带到地址查找然后让他们将地址复制到剪贴板然后返回到送货地址表单的网站设计不会很有用。

REST API 使用我们在 Web 上认为理所当然的模式进行机器与机器交互。

即使每个地址都链接到完整地址和一些编辑链接,也不应该搜索邮政编码功能base/addresses/{postcode}并返回集合,因为那是死胡同;API 使用者需要猜测如何使用该地址。

相反,该功能的动机应该内置到使用它的流程中,以便旅程在开始时结束:

1 GET /orders/123/shipping

  200 OK { Current shipping details + link to parent + link to address picker }

2  -> GET /orders/123/shipping/addresspicker

      200 OK { Link and form for searching for a postcode }

3   -> GET /orders/123/shipping/addresspicker?postcode=tn11tl

       200 OK { List of addresses each with link to pick it }

4    -> POST /orders/123/shipping/addresspicker?postcode=tn11tl&pickNo=3

        200 OK { Current shipping details + link to parent + link to address picker }

这是一个用户旅程,最后您可以看到流程对订单的影响。

HTTP 请求/响应严格来说不是 REST 的一部分,但我认为没有人见过非 HTTP REST 应用程序。

现在这些 URL 可以是任何字符集,它们只是标识符,我把它们做得很漂亮,因为它们对人们有意义。机器会使用rel来计算它们的工作,而不是依赖于可读的href.

于 2018-12-01T12:54:01.757 回答
0

REST API 是遵循 REST 架构约束的 API 实现。它充当接口。客户端和服务器之间的通信通过 HTTP 进行。REST API 利用 HTTP 方法在客户端和服务器之间建立通信。REST 还使服务器能够缓存提高应用程序性能的响应。客户端和服务器之间的通信是一个无状态的过程。我的意思是,客户端和服务器之间的每次通信都像是一个新的通信。

没有从之前的通信中携带的信息或记忆。因此,每次客户端与后端交互时,它都必须将身份验证信息发送给它。这使后端能够确定客户端是否有权访问数据。

通过 REST API 的实现,客户端可以与后端端点进行通信。这完全解耦了后端和客户端代码。

于 2020-05-20T10:54:21.600 回答
0

为了在这里贡献一些新的东西,我想分享我的文章的链接,即通过实用和客观的方法来概念化 REST。

我正在介绍主要概念,例如:

  • HATEOAS - 超媒体作为应用程序状态的引擎,
  • 资源和陈述,
  • 可寻址性,
  • REST 中的幂等性,
  • 理查森的 REST 成熟度模型。
  • 媒体类型
  • API 版本控制

我还创建了一个 GitHub 项目,您可以使用 docker 轻松运行它,它涵盖了我在本文中介绍的内容。

https://itnext.io/how-to-build-a-restful-api-a-deep-dive-into-rest-apis-215188f80854

于 2020-10-21T20:10:41.620 回答
-2

REST 是一种分布式系统(如 WWW)软件架构风格,你可以想象它是一个精心设计的 Web 应用程序规则:一组 Internet 网页(一个虚拟状态机),其中通过点击超链接链接(状态转换),结果是下一个网页(这意味着应用程序的下一个状态)。

REST 描述的网络系统由三部分组成:

  1. 数据元素(资源、资源标识符、表示)
  2. 连接器(客户端、服务器、缓存、解析器、隧道)
  3. 组件(源服务器、网关、代理、用户代理)

REST 严格满足以下条件:

  1. 应用程序功能的状态被拆分为资源
  2. 每个资源用作超链接定位语法(即在 WWW URI 中)
  3. 所有资源在具有资源转换状态的客户端之间共享一个统一的接口,包括:
    1. 一组有限的定义良好的操作(即在 HTTP GET / POST / PUT / DELETE 中)
    2. 一组有限的内容格式内容类型,可能包括可执行代码(即,在 WWW Javascript 中)
于 2013-07-25T08:36:40.933 回答