【问题标题】:RESTful websites vs. RESTful APIs - What's the difference and does it matter?RESTful 网站与 RESTful API - 有什么区别,有什么关系?
【发布时间】:2014-01-13 14:02:53
【问题描述】:

我已经阅读了很多关于 REST 以及如何以“正确方式”进行 REST 的文章。大多数资源使用 RESTful Web 服务或 RESTful API 等术语,但没有提及 RESTful 网站。我对此感到困惑,因为我认为网站和 API 是两个不同的东西。然而,例如,当使用 Rails 框架设计网站时,您会不断地被提醒一切都是 RESTful 的(或应该是)。

我知道 REST 为 API(例如 JSON API)提供了很多优势(其架构属性),但我只是不明白网站如何从 RESTful 中受益。作为一个简单的例子,考虑登录功能。在 REST 方式中,这可以通过创建一个会话模型来建模,其中登录对应于创建一个新会话,注销 销毁一个会话等等。 URL 看起来像这样:

Prefix Verb   URI Pattern                    Controller#Action
    new_user_session GET    /users/login(.:format)         sessions#new
        user_session POST   /users/login(.:format)         sessions#create
destroy_user_session DELETE /users/sign_out(.:format)      sessions#destroy

但是,这些 URL 对用户不是很友好。从用户的角度来看,只有一个显示登录表单的 /login 路径更有意义。它也更容易记住。但是,如果我们像这样制作 URL 映射,它们就不再是真正的 RESTful 了; /login 是否识别资源。如果有,是哪一个?

另一个例子是主页 /home 或只是 /。这如何适应 REST?在大多数网站上,主页是许多不同类型信息的混搭,并不能识别任何单一资源。例如,它可能是一个页面,其中列出了目录中的最新产品以及您上次登录的日期;完全不相关的两件事。 RESTful 怎么样?

我理解为什么将 RESTful API 与网站分开是有道理的,但我的困惑在于 REST 如何应用于网站 - 如果确实如此的话。

【问题讨论】:

  • 我建议删除ruby-on-rails 标签。是的,这个问题使用 RoR 作为鼓励 RESTful Web 应用程序的 Web 框架的示例但是这个问题(及其答案)似乎根本与 RoR 无关。标签web-applicationsweb-api 可能更合适。

标签: ruby-on-rails api rest web


【解决方案1】:

简短的回答是没有人谈论 RESTful 网站,因为网站默认是 RESTful。您确实必须尝试制作一个非 RESTful 网站(尽管已经完成了——见下文)。

您所描述的设置从 REST 中获取了很多元素,但它本身并不是“REST”:它是一组为方便服务器端程序员而设计的约定。当今的大多数 Web API 仅使用 REST 约束的一个子集,并且它是一个不包括网站背后的主要驱动原理的子集。

让我后退一点。以下是网站和 Web API 的共同点:它们都通过资源公开功能。每个资源都由一个 URL 标识,每个资源都响应标准 HTTP 方法的适当子集。 (这似乎很明显,但看看 XML-RPC 或 SOAP,整个系统只有一个 URL。)资源可能会向客户端发送文档(响应 GET 请求)和/或它可能接受来自客户端(连同 POST 或 PUT 请求)。

现在,差异。 Web API 通常将四种最常见的 HTTP 方法(POST、GET、PUT、DELETE)映射到四种 CRUD 操作(创建、读取、更新、删除)上。网站不能这样做,因为网站运行在 HTML 上,而 HTML 表单只支持两种方法:GET 和 POST。然而,一个网站可以很容易地描述各种操作——“搜索”、“下一页”、“购买”、“取消好友”——这些操作映射到 CRUD 上并不简单。

那是因为 HTML 支持链接和表单。这是家谱的“Web API”分支中缺少的内容。不是资源,而是资源之间的机器可读连接。 (抛开一些 REST 术语来说,这是“超媒体约束”或“超媒体作为应用程序状态的引擎”。)

“Web API”倾向于忽略超媒体约束,因为 a) 难以理解,b) JSON 不支持链接或表单,因此即使您愿意也很难遵守超媒体约束。 (随着 JSON-LD、Hydra 和 HAL 等格式的发展,这种情况正在发生变化。)

但超媒体约束实际上是将 Web 连接在一起的原因。拿走链接和表格,你会留下一个无法使用的烂摊子。

Python Challenge 是非 RESTful 网站的一个很好的例子。你得到a starting URL,然后你必须解决一个小难题来弄清楚如何到达序列中的下一个 URL。您仍然有资源,并且每个资源都有一个 URL。但是资源之间的联系是模糊的。作为一款游戏,这很有趣,但没有人会以这种方式运营一个严肃的网站。不幸的是,这就是我们在“Web API”方面所处的位置。

进一步阅读

如您所知,这是一个复杂的话题。冒着自吹自擂的风险,我为 2008 年的一次演讲开发的the "maturity model" 可能会帮助您了解万维网(第 3 级)和当今大多数 API(第 2 级)之间的架构差异。我还推荐 Steve Klabnik 的 Designing Hypermedia APIs 和我自己的 RESTful Web APIs,首先将 Web API 与做同样事情的网站进行比较。

我之前的书RESTful Web Services 也涵盖了这个主题,并且可以在线免费阅读。然而,它有些过时了(它于 2007 年出版),回想起来,我认为它对超媒体角度的推动力度不够。

杂项

简要回答您最初问题中的几个小问题:

  1. Web API 和网站在技术上没有区别。网站是恰好提供 HTML 文档的 Web API。

  2. 一个 URL 并不比另一个 URL 更“RESTful”。这只是一个可用性问题。在技​​术层面上,您的 URL 是什么样的并不重要。 /users/login.json/login/the-first-100-prime-numbers.gif 都是同样的 RESTful 方式来引用登录表单。

  3. 主页是一种资源:它是“主页”资源。它的工作是包含最重要的信息位,并将客户引导至其他页面——直接通过链接,或间接通过搜索表单。资源不一定对应于数据库中的行或对象模型中的对象。资源可以是任何东西,甚至是现实世界的对象或抽象概念。唯一的限制是资源必须有 URL。

  4. /login 是一个 URL,所以是的,它标识了一个资源。什么样的资源?如果这是发送“GET /login”为您提供带有登录表单的 HTML 页面的典型场景,那么它就是“登录表单”资源。如果填写登录表单触发“POST /login”请求,那么它也充当“登录表单处理器”资源。

您可能会更好地考虑资源在请求其 URL 时运行的代码,而不是尝试将其映射到数据集中的一个特定“事物”。也就是说,与其试图弄清楚资源是什么,不如从它做什么的角度来思考它。

希望这会有所帮助。

【讨论】:

  • 绝妙的答案!非常感谢。
  • 我刚遇到这个。在尝试维护应用程序状态时,我发现服务器会话非常有用。那么对于一个网站,而不是 RESTful API,你怎么看?
猜你喜欢
  • 2012-04-21
  • 2010-12-06
  • 2012-10-13
  • 2011-10-30
  • 1970-01-01
  • 1970-01-01
  • 2021-01-08
  • 2016-05-03
  • 2012-03-23
相关资源
最近更新 更多