当服务器是客户端时如何管理 HATEOAS 链接?
How to manage HATEOAS links when the server is the client?
我正在了解 HATEOAS。我正在处理的后端服务器将使用使用 HATEOAS 的第三方 REST API。 API 每个资源的 return 和 url 的终点以及 return 与常规请求相关的资源链接。
但我想知道在服务器上管理这些链接以避免对它们进行硬编码的好方法是什么。例如,如果第三方更改了资源的 url,服务器将如何检测到该更改?是否有任何管理 HATEOAS 资源链接的标准做法?
我能想到的可能的方法
服务器启动时,获取所有资源url并缓存。每当需要调用第三方API时,就复用这些缓存的url。每当出现 404 或相关错误时,更新资源 url。或者每隔一段时间定期更新url。
每次调用端点前获取资源url。最简单但本质上是请求数量的两倍。
但这两种方法听起来都不稳健。
虽然发现通常是一件好事,并且应该允许 HATEOAS 系统以 'hardcoded urls' 不允许的方式引入更改,但如果 url 开始任意中断,我仍然认为这是一个主要问题。
你应该能够在你这边存储 url/链接,并期望它们继续工作。
虽然有一些处理变化的机制:
- 如果资源移动,服务器应该 return
301
/ 308
重定向。如果是这种情况,您还应该更新您的参考资料。
- 服务器可以发出
Sunset
或 Deprecated
headers。参见:https://www.rfc-editor.org/rfc/rfc8594
这些是更笼统的答案,但最终存在最佳实践并不意味着供应商会遵守它们。考虑到这一点,我认为你最好的办法是尝试找出你的供应商的弃用政策,看看他们推荐什么。
- 如果有效则使用缓存资源,当您没有本地有效副本时请求刷新。
RFC 7234 定义了 HTTP 的缓存语义。
理想情况下,您不自己实施缓存规则,而是使用通用缓存。
在理想形式下,您的定制实现是与无头浏览器对话,而无头浏览器会为您担心缓存规则。
理论上,您需要初始 URL 来启动该过程,其他一切都来自于此。
您从服务器获得的每个资源都应包括 link 到该资源服务图上其他边的值。
因此,一旦您获得初始资源,其余所有资源都会自动出现。
也就是说,拥有理想情况下不变的 URL 的“众所周知”的入口点并不是什么坏事。但归根结底,那些只是“书签”,不一定是终点。
考虑一个购物网站,例如亚马逊。在 amazon.com
之外,您不认识他们的任何 URL。它们都以各种形式和页面提供,人们只需浏览网站即可。那些 URL 可以一直在变化,没有人会知道。使用 HATEOAS,跟随 link 取决于机器,而不是人。但是导航的过程是一样的。
正如其他人所提到的,缓存根资源的想法有其优点。然后你依靠缓存 headers 来指导你多久刷新一次 links。
但是也就是说,在操作上,遵循正常的 link 和遵循缓存的 link 之间没有区别。在下面,缓存的资源加载速度更快,但您仍然需要“遵循 link”。因为那是缓存行为开始的地方。这不同于假设 link 是好的,假设您知道资源查找的结果。您的申请遵循 link。总是。底层基础架构负责使其高效。
因此,您的代码不应加载根资源,然后填充充满 link 的地图,然后假设它们是好的。相反,代码应该请求根资源,可能是 links 的 Map(win 的数据类型),并让下一层处理细节。因为这完全取决于所涉及的缓存类型。有些已经编码了不需要跟进的持续时间。其他人,无论如何你发出请求,服务器层响应“没有改变”,所以你可以使用你的本地副本,但你仍然需要首先询问。
这些是服务器(不是客户端)要求的实现细节。这是一个服务器合同。如果他们希望您每次都对他们执行 ping 操作,那就这样吧。这就是他们提供给您的合同,如果您想成为一名好公民,那么您应该尊重该合同。
理想情况下,服务器会为了效率而在这些问题上做出正确的决定,但最终还是取决于他们。
客户必须同意。 HATEOAS 系统中的客户端向服务器让步很多。它们根本不是由客户做出的决定。
我正在了解 HATEOAS。我正在处理的后端服务器将使用使用 HATEOAS 的第三方 REST API。 API 每个资源的 return 和 url 的终点以及 return 与常规请求相关的资源链接。
但我想知道在服务器上管理这些链接以避免对它们进行硬编码的好方法是什么。例如,如果第三方更改了资源的 url,服务器将如何检测到该更改?是否有任何管理 HATEOAS 资源链接的标准做法?
我能想到的可能的方法
服务器启动时,获取所有资源url并缓存。每当需要调用第三方API时,就复用这些缓存的url。每当出现 404 或相关错误时,更新资源 url。或者每隔一段时间定期更新url。
每次调用端点前获取资源url。最简单但本质上是请求数量的两倍。
但这两种方法听起来都不稳健。
虽然发现通常是一件好事,并且应该允许 HATEOAS 系统以 'hardcoded urls' 不允许的方式引入更改,但如果 url 开始任意中断,我仍然认为这是一个主要问题。
你应该能够在你这边存储 url/链接,并期望它们继续工作。
虽然有一些处理变化的机制:
- 如果资源移动,服务器应该 return
301
/308
重定向。如果是这种情况,您还应该更新您的参考资料。 - 服务器可以发出
Sunset
或Deprecated
headers。参见:https://www.rfc-editor.org/rfc/rfc8594
这些是更笼统的答案,但最终存在最佳实践并不意味着供应商会遵守它们。考虑到这一点,我认为你最好的办法是尝试找出你的供应商的弃用政策,看看他们推荐什么。
- 如果有效则使用缓存资源,当您没有本地有效副本时请求刷新。
RFC 7234 定义了 HTTP 的缓存语义。
理想情况下,您不自己实施缓存规则,而是使用通用缓存。
在理想形式下,您的定制实现是与无头浏览器对话,而无头浏览器会为您担心缓存规则。
理论上,您需要初始 URL 来启动该过程,其他一切都来自于此。
您从服务器获得的每个资源都应包括 link 到该资源服务图上其他边的值。
因此,一旦您获得初始资源,其余所有资源都会自动出现。
也就是说,拥有理想情况下不变的 URL 的“众所周知”的入口点并不是什么坏事。但归根结底,那些只是“书签”,不一定是终点。
考虑一个购物网站,例如亚马逊。在 amazon.com
之外,您不认识他们的任何 URL。它们都以各种形式和页面提供,人们只需浏览网站即可。那些 URL 可以一直在变化,没有人会知道。使用 HATEOAS,跟随 link 取决于机器,而不是人。但是导航的过程是一样的。
正如其他人所提到的,缓存根资源的想法有其优点。然后你依靠缓存 headers 来指导你多久刷新一次 links。
但是也就是说,在操作上,遵循正常的 link 和遵循缓存的 link 之间没有区别。在下面,缓存的资源加载速度更快,但您仍然需要“遵循 link”。因为那是缓存行为开始的地方。这不同于假设 link 是好的,假设您知道资源查找的结果。您的申请遵循 link。总是。底层基础架构负责使其高效。
因此,您的代码不应加载根资源,然后填充充满 link 的地图,然后假设它们是好的。相反,代码应该请求根资源,可能是 links 的 Map(win 的数据类型),并让下一层处理细节。因为这完全取决于所涉及的缓存类型。有些已经编码了不需要跟进的持续时间。其他人,无论如何你发出请求,服务器层响应“没有改变”,所以你可以使用你的本地副本,但你仍然需要首先询问。
这些是服务器(不是客户端)要求的实现细节。这是一个服务器合同。如果他们希望您每次都对他们执行 ping 操作,那就这样吧。这就是他们提供给您的合同,如果您想成为一名好公民,那么您应该尊重该合同。
理想情况下,服务器会为了效率而在这些问题上做出正确的决定,但最终还是取决于他们。
客户必须同意。 HATEOAS 系统中的客户端向服务器让步很多。它们根本不是由客户做出的决定。