所以,我正在学习 Ruby on Rails。我掌握了应用程序架构的 RESTful 方法的基础知识,但我还没有完全构建 RESTful 应用程序。
在传统的 Web 应用程序中,幂等请求(不会更改任何状态)是通过 HTTP 的 GET
方法发出的,所有非幂等请求通常都是通过 POST
方法。为了让应用程序区分 POST
请求可能触发的不同操作,表单中通常有一个隐藏字段包含在 POST
请求中,例如 action=delete
或 action=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 中,PUT
和 DELETE
由 JavaScript 实现,它将您的链接更改为带有名为 _method
的隐藏字段的表单。通过 POST
从浏览器接收表单,然后 Rails 查找此字段并决定是否将请求路由到 PUT
或 DELETE
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
intoPOST
http://server.tld/resource/1?_method=DELETE
, then what's the advantage of that approach over just usingPOST
http://server.tld/resource/1?my_method=delete
in the first place?
- 就 API 设计而言,它使总体目标更清晰/更清晰。 REST 框架最终只能在人们使用它们时成为 RESTful,因为 REST 是一种架构风格,而不是协议(protocol)或实现。
- 此外,严格来说,URI 包含查询部分,所以
http://server.tld/resource/1
和http://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/