gpt4 book ai didi

single-page-application - 如何在 HATEOAS 服务器上实现深度链接客户端?

转载 作者:行者123 更新时间:2023-12-03 01:30:41 26 4
gpt4 key购买 nike

There's a similar question on SO, but it's not phrased well and it lacks details. So I'm trying to write a better question.



我对如何使用使用 pushState 的单页应用程序 (SPA) 实现 HATEOAS 感兴趣。 .我想保留深层链接,以便用户可以在 SPA 中为 URL 添加书签,并在以后重新访问它们或与其他用户共享它们。

为了具体起见,我将举一个假设的例子。我的单页应用程序托管在 https://www.hypothetical.com/ .当用户在浏览器中访问此 URL 时,它会下载一个 SPA 和 bootstrap 。 SPA 查看浏览器的当前 location.href以确定要获取和呈现的 API 资源。在根 URL 的情况下,它请求 https://api.hypothetical.com/ ,它会呈现如下响应:
{
"employees": "https://api.hypothetical.com/employees/",
"offices": "https://api.hypothetical.com/offices/"
}

我正在掩盖一些细节,例如 acceptcontent-type ,但让我们假设这个假设的 API 支持内容协商和其他 RESTful 优点。

现在 SPA 呈现一个用户界面,向用户显示这两个链接关系,用户可以单击“员工”按钮查看员工或“办公室”查看办公室。假设用户单击“员工”。 SPA需要 pushState()一些新的href,否则这个导航决定将不会出现在历史记录中,用户将无法使用后退按钮返回到第一个屏幕。

这带来了一个小困境:SPA 应该使用什么 href ? 显然,它不能推送 https://api.hypothetical.com/employees/ .这不仅不是 SPA 内的有效资源,而且它甚至不在同一来源和 pushState() 中。如果新的 href 来自不同的来源,则抛出异常。

困境 [也许] 很容易解决:SPA 知道一个名为 employees 的链接关系。 ,因此 SPA 可以硬编码此资源的 URL: pushState(...,'https://www.hypothetical.com/employees') .接下来,它使用链接关系 https://api.hypothetical.com/employees/获取员工集合。 API 返回如下结果:
{
"employees": [
{
"name": "John Doe",
"url": "https://api.hypothetical.com/employees/123",
},
{
"name": "Jane Doe",
"url": "https://api.hypothetical.com/employees/234",
},
...
]
}

有两个以上的结果,但我用省略号进行了缩写。

SPA 希望将此数据显示在表中,其中每个员工的姓名都是一个超链接,以便用户可以查看有关特定员工的更多详细信息。用户点击“John Doe”。 SPA 现在需​​要显示有关 John Doe 的详细信息。它可以使用链接关系轻松获取资源,它可能会得到如下内容:
{
"name": "John Doe",
"phone_number": "2025551234",
"office": {
"location": "Washington, DC",
"url": "https://api.hypothetical.com/offices/1"
},
"supervisor": {
"name": "Jane Doe",
"url": "https://api.hypothetical.com/employees/234"
},
"url": "https://api.hypothetical.com/employees/123"
}

但现在同样的困境再次出现:SPA 应该选择什么 URL 来表示这种新的内部状态? 这与上面的困境相同,除了这次不可能对单个 SPA URL 进行硬编码,因为有任意数量的员工。

我认为这是一个不平凡的问题,但让我们做一些 hacky 以便我们可以继续前进:SPA 通过将主机名中的 'api' 替换为 'www' 来构造一个 URL。它非常丑陋,但它并没有违反 HATEOAS(SPA URL 仅用于客户端),现在 SPA 可以 pushState(...,'https://www.hypothetical.com/employees/123' .概括这种方法,SPA 可以显示任何链接关系的导航选项,用户可以浏览相关资源:此人的办公室在哪里?主管的电话号码是多少?

这仍然不能解决深层链接。 如果用户添加书签怎么办 https://www.hypothetical.com/employees/123 , 关闭浏览器,然后稍后重新访问此书签?现在 SPA 不记得底层 API 资源是什么。我们无法逆转替换(例如,将 'www' 替换为 'api'),因为那不是 HATEOAS。

HATEOAS 的心态似乎是 SPA 应该请求 https://api.hypothetical.com/再次点击链接回到 John Doe 的员工文件,但没有固定的链接关系可以从 employees 获得。收藏到 John Doe作为一个特定的员工,所以这是行不通的。

另一种 HATEOAS 方法是应用程序可以为它发现的 URL 添加书签。例如,它可以存储一个哈希表,将之前看到的 SPA URL 映射到 API URL:
{
"https://www.hypothetical.com/employees/123": "https://api.hypothetical.com/employees/123"
}

这将允许 SPA 找到底层资源并呈现 UI,但它需要跨 session 的持久状态。例如。如果我们将此散列存储在 HTML5 存储中并且用户清除他们的 HTML5 存储,那么所有书签都会损坏。或者,如果用户将此书签发送给另一个用户,则该用户将不会拥有 SPA URL 到 API URL 的映射。

底线:在 HATEOAS API 之上实现深层链接 SPA 对我来说感觉很尴尬。在我当前的项目中,我使用 SPA 来构建几乎所有的 URL。作为该决定的结果,API 必须为各个资源发送唯一标识符(不仅仅是 URL),以便 SPA 可以为它们生成好的 URL。

有没有人有这样做的经验?有没有办法满足这些看似矛盾的标准?

最佳答案

我可能遗漏了一些东西,但大概对于不同的资源类型,您有不同的 View /页面。因此,当您加载员工时,它使用employees.html View ,而当您找到员工时,您使用employee.html View ..所以为什么会更像这样

//user clicks employees
pushState( "employees.html#https://api.hypothetical.com/employees/" )

//user clicks on an employeed
pushState( "employee.html#https://api.hypothetical.com/employees/12345/" )

我的意思是 URI 组件肯定会对 url 进行编码……但是现在您有了指向资源 View 的深层链接,不需要 hack。

我看到 pushState 但实际上它可能更准确地被认为是 pushViewState

关于single-page-application - 如何在 HATEOAS 服务器上实现深度链接客户端?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29040388/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com