【问题标题】:What exactly is REST architecture and how is it implemented in Rails?REST 架构到底是什么?它是如何在 Rails 中实现的?
【发布时间】:2011-02-20 21:19:15
【问题描述】:

这就是我对 REST 架构的看法。

对于每个资源,都有一个唯一的 URI。

我们可以使用它的 URI 和 HTTP 操作 [POST、GET、PUT 和 DELETE] 来操作该对象。 HTTP 请求传输该对象的状态表示。

在我读过的所有文章中,REST 都以一种奇怪而令人困惑的方式解释。

还有一点,rails 中的 RESTFUL 实现会为不同的目的生成不同的 url。像 /teams -> for 'index' 方法... /teams/new -> for 'new' 方法等等。这不是远离rest,它定义了每个资源都有一个唯一的URI???

【问题讨论】:

    标签: ruby-on-rails rest


    【解决方案1】:

    我认为您对 REST 的理解非常好。它不需要比它应该的更复杂。 @Surya 还概述了一些非常好的观点。

    Rails 将 HTTP 方法映射到控制器方法的方式是:

    GET    => show
    PUT    => update
    POST   => create
    DELETE => destroy
    

    rails 提供的另外两种资源/方法:

    resource/new  => new
    resource/edit => edit
    

    很可能不是用于所有实际目的的资源,但对于构​​建网页和应用程序是必需的。如果客户完全了解资源,则不需要这些。客户端只需使用资源信息进行POSTPUT 调用,并根据需要创建或更新资源。但由于不希望用户了解资源的来龙去脉,因此他们需要一个更简单的界面来进行创建或更新。

    如果所有用户都完全了解资源并且对命令行足够熟练,我们甚至不需要 HTML。他们可以在与这些资源的交互中 curl :)

    index 只是让使用集合变得更容易。它仍然是一个定义明确的资源并且具有唯一的表示,例如/books。它在服务器端代码上的处理方式并没有使它成为RESTless(我只是编造的,但它很棒)。

    【讨论】:

    • @Darell /foo 是对象的集合。 /foo/1 是对象集合中的单个对象。它可能是一个集合,也可能不是。 /foo/edit 将对象 id 作为参数,因此它代表同一个对象。假设它与 /foo/1 对象上的 PUT 请求的工作相同。
    • @Jagira 我完全理解这些不同的 Url 旨在对同一个域对象进行操作。不幸的现实是,在应用 REST 的约束时,您需要将它们视为完全不同的资源。这是一个微妙但重要的区别。
    【解决方案2】:

    我将从 Roy Fielding 的论文中的chapter 5 开始。有几个基本原则:

    • 资源:资源通常可以是您作为服务的一部分向外界公开的东西。重点是识别资源(例如:Book、UserList、CalculateDistance)
    • URI:给每个资源一个标识符(例如:example.com/books/7654)
    • 统一接口:使用标准方法,如 GET、PUT。 POST、DELETE、HEAD、OPTIONS
    • 表示:一个资源可以有多个表示。例如,对一本书的 GET 可以返回该书内容的 PDF、内容的 HTML,甚至是带有书籍封面的 GIF 等等。表示本质上是所有数据和标记的集合。
    • 超媒体:在我看来,这是一个非常重要的原则。这一原则的实现使您的应用程序远远领先于 REST 风格的常规类似 CRUD 的定义。 HATEOAS 是 Hypermedia 作为应用程序状态引擎的缩写。当您单击链接或提交表单时,您正在更改应用程序的状态,这是通过超链接(或超媒体)发生的。服务器和客户端之间几乎没有耦合。客户端通过服务器提供的链接浏览应用程序。 (在博客圈里有很多关于这个原则的讨论……)【另请看Restfulie

    我最近在answered a question 上找到了学习 REST 的好资源,可能会有所帮助。

    我不熟悉 Rails,所以不解决这部分问题。

    【讨论】:

      【解决方案3】:

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

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

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

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

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

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

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

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

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

      【讨论】:

      • 顺便说一句,我刚刚意识到我从未解决过 Rails 问题。我为此道歉。虽然我个人使用 Django 来处理服务器端的事情,但 Django 和 Ruby on Rails 都用于开发应用程序服务器。基本上,这意味着它们都用于适当地响应 HTTP 方法(GET、POST 等)。因此,例如,当我请求一个给定的页面 URL 时,我通常在 URL 上执行一个 GET 请求,然后应用程序服务器返回它。如果我将数据 POST 到表单,则应用程序服务器将通过验证数据并可能保存它来响应。
      【解决方案4】:

      您可能注意到有 4 个 HTTP 操作,但典型 Web 应用程序中的基本 CRUD 操作需要 7 个不同的操作。其中一些实际上并没有做任何事情(如/new:id/edit),因此与REST 架构有点平行。此外,索引操作并不作用于资源,而是作用于资源集合(因此也是唯一的 url)。

      所以基本的 4 个 HTTP 操作映射到这样的资源:

      • 获取要显示的地图 -> get /teams/:id
      • PUT 地图更新 -> put /teams/:id
      • 删除要销毁的地图 -> delete /teams/:id
      • POST 有点例外,因为资源还不存在,因此它映射到基础/teams

      总结一下:每个资源都有自己独特的 url,而且 rails 定义了一些额外的 url 用于 UI 和收集目的。

      【讨论】:

        【解决方案5】:

        喜欢 /teams -> 对于“索引”方法... /teams/new -> 用于“新”方法等 在。这不是远离休息吗, 它定义了每个资源都有 一个唯一的 URI???

        不,这并没有远离 REST,因为就 REST 而言,/teams/teams/new 是两种不同的资源。

        【讨论】:

          猜你喜欢
          • 2010-09-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-15
          相关资源
          最近更新 更多