ruby-on-rails - Rails 的 REST 实现怎么能说是 REST?

标签 ruby-on-rails rest

所以,我正在学习 Ruby on Rails。我掌握了应用程序架构的 RESTful 方法的基础知识,但我还没有完全构建 RESTful 应用程序。

在传统的 Web 应用程序中,幂等请求(不会更改任何状态)是通过 HTTP 的 GET 方法发出的,所有非幂等请求通常都是通过 POST方法。为了让应用程序区分 POST 请求可能触发的不同操作,表单中通常有一个隐藏字段包含在 POST 请求中,例如 action=deleteaction=add_to_foo_file。这是一个相当简单的架构,并且在今天非常普遍,但是 REST 方法引导我们远离它并建议“让我们发布所有内容!”设计被认为是有害的。

相反,RESTful 架构让我们通过唯一标识它们的 URI(名词)和 HTTP 请求方法(动词)来操纵资源,而不是根据请求中的单独字段确定要采取的操作:

GET    => show the resource
PUT    => update the resource
POST   => create a new resource
DELETE => destroy the resource

现在我们来谈谈 Ruby on Rails。在 Rails 中,PUTDELETE 由 JavaScript 实现,它将您的链接更改为带有名为 _method 的隐藏字段的表单。通过 POST 从浏览器接收表单,然后 Rails 查找此字段并决定是否将请求路由到 PUTDELETE Controller 的方法。

等等,什么?这听起来很像——甚至完全像——传统网络应用程序的行为,它通过 POST 接收所有状态更改请求,并检查特定字段以决定是销毁还是修改记录。

那么怎么能说 Rails 的方法完全是 RESTful 的,因为在幕后,它只是重新实现了“让我们发布所有内容”的方法,REST 特别试图离开?

而且,对于在浏览器中关闭 JS 的用户,这种方法是否会阻止我的 Rails 应用正常降级?

最佳答案

使系统是否符合 REST 风格与其说是它使用的动词,不如说是交互是由超媒体驱动的事实(在本例中,这包括按需代码 JavaScript)。

您引用的 GET/PUT/POST/DELETE 映射适用于 CRUD 操作,但不一定适用于所有情况(并且不一定受所有浏览器支持)。这是设计 RESTful 系统的合理经验法则,但它既不充分也没有必要。 (这与人们在需要“RESTful”URI 时坚持的想法属于同一类想法:没有这样的东西。)

这部分受到书籍的影响,如 RESTful Web Services .这是一本好书,但它是在 WS-*/SOAP 占主导地位并且一切都通过 POST 隧道化的时候问世的。对 SOAP 的一种 react 是让人们意识到他们可以使用其他 HTTP 动词。

对于 REST,真正重要的是尊重 URI 概念背后的概念,每个 HTTP 动词的语义(无副作用,幂等请求,...,在适当的情况下,如果您使用 HTTP)和 HATEOS 原则。这是一种架构风格,不要过分强调 JavaScript 在底层做了什么 POST/PUT/DELETE。

你当然应该阅读这些:

编辑:(以下评论)

What I should have said was this: If most frameworks turn DELETE http://server.tld/resource/1 into POST http://server.tld/resource/1?_method=DELETE, then what's the advantage of that approach over just using POST http://server.tld/resource/1?my_method=delete in the first place?

  • 就 API 设计而言,它使总体目标更清晰/更清晰。 REST 框架最终只能在人们使用它们时成为 RESTful,因为 REST 是一种架构风格,而不是协议(protocol)或实现。
  • 此外,严格来说,URI 包含查询部分,所以http://server.tld/resource/1http://server.tld/resource/1?my_method=DELETE原则上可以识别不同的资源(尽管这不是一个好的设计选择)。
  • 框架能够公开DELETE是件好事/PUT直接如此,但通过 POST 有一个后备解决方案对于不支持它的客户。

    原因是支持 DELETE 的客户端/PUT将能够使用它们,并对它们的使用做出假设。对于客户端来说,将请求视为非幂等并不是什么大问题,即使它在原则上是幂等的。如果客户端认为它最多可以发送 1 个请求(非幂等),而它本可以发送 N+1 个请求,这不会造成重大问题;如果客户端认为它可以针对不应该是幂等的东西发送 N+1 次相同的请求,这可能会导致很多问题。模拟 PUT通过POST没关系,你只是没有充分利用 PUT , 模拟 POST通过PUT会有问题。

关于ruby-on-rails - Rails 的 REST 实现怎么能说是 REST?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11693959/

相关文章:

ruby-on-rails - rails : Devise: Undefined Method `username'

ruby-on-rails - Ruby on Rails - Controller 更改未被识别

Ajax 调用 : big differences between server runtime and client waiting time

ruby-on-rails - 在运行时生成新模型和模式

ruby-on-rails - 为什么长臂猿会抛出 'uninitialized constant Gibbon::API (NameError)'

python - 等效于 Python 中的 @Named API 参数

xml - 使用 JME(或 J2ME)使用 REST 服务

java - Java 中的 REST Get 调用用于分页

使用 jersey 的 REST 服务输出中的 java.util.Map

ruby-on-rails - 在 seeds.rb 中模拟时间戳