是仅用于 Web 服务还是用于 Web 服务和网页?
Posted
技术标签:
【中文标题】是仅用于 Web 服务还是用于 Web 服务和网页?【英文标题】:is restful meant for web services only OR for both web services AND web pages? 【发布时间】:2010-03-06 08:01:48 【问题描述】:我阅读了很多关于 php 的 Restful 教程。
(我不想深入探讨为什么我不使用 RoR。这是由于团队更熟悉 PHP)
因为我们计划在未来扩展 API,所以我了解到实现 Restful Web 服务很重要。
我看过诸如
之类的教程http://www.gen-x-design.com/archives/create-a-rest-api-with-php/
显然 restful 是为 web 服务设计的。
网页呢?他们也可以安静吗?
如果答案是否定的,请不要越过这条线,直接告诉我。谢谢。
我知道让 url 看起来像 RESTFUL url 就是简单地使用 mod_rewrite。但是,我很确定,restful 架构不仅仅是让 url 看起来不错。
例如,我在名为 list.php 的网页上有一个项目列表。每个项目旁边都有一个删除链接。例如,list.php?id=1&deleteitem
当有人点击 list.php?id=1&deleteitem 链接时,我当然会回到同一个 list.php 文件并检查 $_GET 中的参数 deleteitem。
如果检测到,我将根据 $_GET 中的参数 id 从数据库中删除。
之后我将重定向回 list.php 没有任何参数。
我想知道,如何让整个流程变得 RESTFUL?
我问是因为在 REST 中,要删除某些内容,您需要使用 HTTP 请求方法 (DELETE)。
很明显,在我的链接中,它们都只是简单的<a href="list.php?id=1&deleteitem">Delete</a>
请赐教。
我的编程能力不是很强,如果给出的建议可以尽可能通俗一点就好了。
谢谢。
编辑
我有 2 个后续问题。
问题 1) 由于这是一个带有分页的项目列表,如果我想让它成为 RESTful,该 URL 会是什么样子?
问题 2)由于我将删除链接放在列表中的每个项目旁边,我现在明白了,我应该使用
<form method="POST">
<input type=hidden name="_method" value="delete">
<input type="submit" >
</form>
改为。
不过表格应该贴到哪里呢?项目网址? /items/item-id
但我想在成功删除数据库中的行后返回此列表页面显示成功消息。
当我用成功消息刷新此列表页面时,我还想避免弹出消息。
如果我发回这个 list.php 网址,那么它不是 RESTful 是吗?因为下面的答案告诉我,每个项目都是需要自己的 url 的资源。
请赐教。谢谢。
【问题讨论】:
【参考方案1】:RESTful 是指 Web 服务时常用的,但它可以很好地应用于网页。简而言之,RESTful 就是处理资源。资源可以是一个人、一本书、一部电影、一个剧院、一张票,或者任何你喜欢的东西。
您可以对资源执行四种基本操作。
创建(POST) 读取 (GET) 更新(PUT) 删除(DELETE)大多数网络浏览器不支持PUT
和DELETE
操作,因此您只能使用 POST 操作来发送数据。 Rails 通过传入一个名为 _method
的隐藏参数来伪造 PUT 和 DELETE,框架会根据该值获取并路由它。
此外,您绝不应将GET
用于任何破坏性操作。任何更改资源状态的操作都应使用POST
、PUT
或DELETE
调用,具体取决于更改(如果需要,使用 POST 进行假 PUT/DELETE)。
我建议您检查一下 Rails 中处理 RESTful 路由的方式,只是为了了解一下,如果没有别的。尽管以上四种操作足以以任何可能的方式修改资源,Rails 还引入了其他三种听起来很有用的操作。
索引(所有项目的列表视图) new(通常是一个表单视图来添加一个新的 资源) 编辑(通常是表单视图 更新现有资源)在设计 RESTful 网站时,漂亮的 URL 肯定是摆在桌面上的,但最大的胜利可能是代码质量会自动提高。如果您只处理资源,并且只有四种可能的操作可以应用于资源,那么事情就会开始自行清理。
编辑 1: 自我描述的 URL 是首选,这将使您的生活更轻松,但没有什么可以阻止创建唯一标识资源并使用 HTTP 动词管理它的神秘 URL。以下 URL(使用 md5)来唯一标识资源是完全 RESTful 的。
// represents a person "John Doe"
http://example.com/4c2a904bafba06591225113ad17b5cec
// represents the movie "Lord of the Rings: The Two Towers"
http://example.com/1d9198260dec7bda3fb21e232d60fec3
// represents the "Formula One" sport
http://example.com/fs340as?id=23xa12&type=SP012Ts
这就是代表性状态转移。 MD5 散列就像是保持不变的资源的邮寄地址。表示可以是电影的详细信息(在 html/xml/json/等中),也可以是电影本身的视频,具体取决于客户端的功能。
编辑 2:
假设您有一个资源,它是世界的集合 - countries
。
它可以用 URI 和 HTTP 动词表示,例如:
GET /countries
由于分页是应用程序的属性而不是资源本身,您可以提供查询字符串参数来控制它。
GET /countries?page=1
一个国家也是一种资源,它是国家资源的一部分。您可以使用如下 URL 来识别国家/地区:
/countries/<id>
可以用这些动词对这个国家进行操作:
GET /countries/<id>
POST /countries -- the new country has no existing representation
PUT /countries/<id>
DELETE /countries/<id>
【讨论】:
我有一个问题。对于使用 POST 的表单,我不希望我的用户在使用浏览器上的后退和刷新按钮时看到弹出窗口。那么我如何在仍然保持 RESTful 的同时克服这个问题呢? 查看这个问题,了解如何解决这个问题:***.com/questions/660329/… 我对所有项目的列表视图有疑问。我对 Rails 不太熟悉,所以我不得不问你。对于列表的分页,RESTful 框架将如何处理它? 这是一个小细节.. 最重要的是要记住构成资源的内容。如果您每页分页 10 个国家/地区,那么每个国家/地区页面是否构成您的资源?如果是这样,请将其作为 URI 本身的一部分。否则将其放在查询字符串参数中。 是的。因为您要删除像/countries/43
这样的资源,所以它也将是 URL(表单操作)。该方法将是DELETE
,就像您提到的那样。删除完成后重定向到/countries
可以是服务器端的隐式知识,也可以像您所说的那样由客户端请求作为引用参数。【参考方案2】:
长答案短:是的。 REST 适用于两者。那是因为即使您拥有所有网站中最简单的网站,您仍然需要获取您的页面并可能发布个人数据才能将条目添加到留言簿。因为我们都以某种方式坚持 REST。
在您的情况下,糟糕的浏览器实现很难实现 PURE RESTful 方式。如果没有 javascript,则不支持 DELETE,因此无论如何您都必须使用 GET 或 POST(两者的含义与 REST 中的 DELETE 完全不同)。
【讨论】:
【参考方案3】:Restful 方法当然也可以在网页中使用。由于您提到的副作用,将命令放入 URL 不是一个好主意。当您更改数据库(或执行任何更改模型的操作)时,请使用 POST 命令。
当然,您在主流网络浏览器中没有 PUT 和 DELTE,但您始终可以发送带有一些特定参数的简单 POST,例如 method
= "PUT"、method
="DELETE" 等。
【讨论】:
我会调用参数 method=PUT 或 method=DELETE :D aefxx:好主意,当然“方法”比“工作”更有意义 我有一个问题。对于使用 POST 的表单,我不希望我的用户在他们使用浏览器上的后退和刷新按钮时看到弹出窗口。那么我如何在仍然保持 RESTful 的同时克服这个问题呢? 您可以使用en.wikipedia.org/wiki/Post/Redirect/Get避免重复提交表单【参考方案4】:我在 Zend Framework 之上编写了一个小型框架,以便更轻松地实现 RESTful 接口:
http://github.com/mikekelly/Resauce
您可以将其用于网络服务和网站。本质上,网站只是一个由 HTML 驱动的网络服务。
【讨论】:
由于某些原因,我们没有使用 Zend Framework。如上所述,我仍然可以使用 Resauce 来帮助我吗?谢谢。 Resauce 是由 ZF 的 MVC 组件构建的——所以不是。还有其他项目,如胶水 (gluephp.com/about)、Limonade 等。【参考方案5】:RESTful 不是“漂亮的 URI”。尽管 URI 标识了资源,但 REST 关于 URI 的唯一说明是,它们不应包含诸如“删除”之类的操作参数。
在你的情况下,你会打电话给
DELETE /items/6793
答案通常是状态代码200 OK
,修改后的列表作为消息正文。见:http://restpatterns.org/HTTP_Methods/DELETE
由于 HTML 4 不支持除 GET 和 POST 之外的其他表单操作,因此您必须使用隐藏参数解决方法并覆盖服务器端的 HTTP 方法。
【讨论】:
即使我使用表单 POST 删除该项目,我将如何重定向回列表页面?我已编辑我的问题以包含此查询以上是关于是仅用于 Web 服务还是用于 Web 服务和网页?的主要内容,如果未能解决你的问题,请参考以下文章
用于托管 WCF 集成服务的 Azure Web 应用程序或云服务