【问题标题】:URL handling in a Hypermedia (HATEOAS) driven AngularJS application超媒体 (HATEOAS) 驱动的 AngularJS 应用程序中的 URL 处理
【发布时间】:2015-07-14 22:25:27
【问题描述】:

我们正在寻找一些关于在由 HATEOAS REST API 支持的 Web 应用程序中处理 URL(以及与每个 URL 相关的状态)的建议,更具体地说是在

  • 如何避免将 Web 应用程序 URL 与 REST API URL 耦合
  • 如何在一个视图中处理多个资源

但让我先提供更多背景信息:

我们正在一个带有超媒体约束的 REST 层之上构建一个 Angular Web 应用程序。 (注意:我更喜欢简单地使用术语“超媒体(约束)”而不是 HATEOAS)。

按照超媒体约束的规定,应用程序中任何时间点的可用操作和链接都由 REST API 提供。因此,Web 应用程序不应包含 REST API 的任何硬编码 url,除了“根”(假设该概念确实存在于 REST API 中)。

另一方面,Web 应用程序中的每个页面都需要可添加书签。所以我们不能创建一个黑盒应用程序(在不更改 URL 的情况下,在 SPA 中处理单个 URL 和所有状态更改)。这意味着 Web 应用程序也有它的 URL 空间,它需要以某种方式映射到 REST API URL 空间。这已经与超媒体理念相冲突了。

在 Angular 应用程序中,我们使用 UI Router 来处理应用程序状态。以下是我们的工作方式:

  • 我们只定义状态,没有 URLs
  • 我们定义了一个 $urlRouterProvider.otherwise 处理程序,它将当前 Web 应用程序 URL 映射到相应的 REST API URL,检索与该 REST URL 对应的资源的表示并将其传递给控制器​​(在 $stateParams 中)。
  • 然后控制器可以使用表示中的数据(以及链接和操作),就像它自己(或通过服务)调用 REST 一样

到目前为止一切都很好(或不是真的),因为这种方法有一些缺点:

  • Web 应用程序 URL 映射到 REST API URL,因此两个 URL 空间是耦合的,这与使用超媒体约束的基本假设之一相冲突:我们无法在不更改 Web 应用程序的情况下更改 REST API URL。
  • 在 $urlRouterProvider.otherwise 处理程序中,我们检索当前 Web 应用程序 URL 的表示。但在某些情况下,我们在单个视图中有两个资源(使用 UI Router 嵌套状态):例如项目列表和单个项目的详细信息。但是只有一个 URL,因此只检索项目详细信息的表示形式,项目列表保持为空。

因此,我们很想听听一些关于如何改进处理这两个 URL 空间的方法的建议。有没有更好的方法让 REST API 决定 Web 应用程序的(可用)行为,并且在 Web 应用程序中仍然有可收藏的 URL?因为现在我们有某种感觉并不完全正确的混合方法。

提前致谢。

问候,

卢克

【问题讨论】:

    标签: angularjs web-services rest hateoas hypermedia


    【解决方案1】:

    这是一个艰难的设置。大致而言,您希望在 API 中添加书签,而 RESTful 系统在某种程度上不鼓励使用书签。

    一种可能的解决方案是“书签服务”,它为当前正在呈现的资源返回书签(有点像)url,这些url保证是向前兼容的,因为您可以更改规范的url结构,书签服务总是可以将 bit.ly like url 翻译成规范的 url。听起来很复杂,但我们经常看到这一点,我们称它们为 SEO 网址,例如:/product-name/ 今天映射到 products/,但明天可能是 /catalog/old-products/。

    如何将其与显示 2 个资源的 UI 相匹配,第一个是资源摘要列表,第二个是特定资源获取真的很棘手。我希望这样的页面知道包含它在其 url 中显示的状态(可能在片段中)。因此,因为它[可能]是处理此类命令的控制器,它可能需要(列表资源和扩展资源)作为输入。我敢打赌网址看起来像:

    list=http://path/to/list/results&expand=http://self/link/of/path

    因此,您要做的最后一部分是确保继续进行。这又是书签问题。如果您不想构建书签服务,我可能会建议的是,如果您想要拥有这样的书签,您需要将人们转移到新的 URL。当向 http://path/to/list/results 发出请求并且您想要切换它时,您应该 301 将它们重定向到新的规范 url,并且应用程序应该更新书签。这样的重定向可以包含 &flag=deprecate_message 参数以触发 UI 中客户端的书签已旧并且应该被替换的呈现。或者,可以在内部转发响应,并将弃用标志和规范(或最新)链接包含在对旧 URL 的响应中。这会导致阶段性转变。

    总而言之:我还没有看到 HATEOAS 可以解决所有向后和向前兼容性问题,但它比现有技术要好得多。也就是说,您仍然必须在 API 的 v1 中决定您希望用户如何迁移到 v2。

    【讨论】:

    • 感谢您花时间为这个相当复杂的设置提出一些好的建议。我喜欢书签服务的想法。这似乎是一个很好的解决方案,可以将 UI url 空间与 REST url 空间分离。对于单个视图中的 2 个资源,我们能够通过添加从详细资源到其父列表资源的链接来解决它。提供我们所需结果的“纯”超媒体解决方案。
    • 克里斯的所有优点。我知道这是一篇过时的帖子,但对于未来的 SO 搜索者,我会补充一点(除了上述方法之外),您应该在返回资源链接列表时考虑返回“书签”关系类型。请参阅w3.org/TR/html5/links.html#link-type-bookmark 了解更多信息。
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2016-12-24
    • 2023-03-22
    • 2022-12-25
    • 1970-01-01
    • 2021-02-06
    • 2013-11-29
    • 1970-01-01
    相关资源
    最近更新 更多