通过RESTful最佳服务,HATEOAS原则告诉我们,我们不应该允许客户端构建资源URL-s。如果我们遵循这个原则,那么分享客户端的当前状态将非常困难。例如,如果您在服务器上有REST服务,并且您通过AJAX使用单页javascript客户端获取数据,那么您将拥有2个URL。一个用于客户端状态,另一个用于从REST服务获得的结果。由于pushState,您只能共享客户端状态...如果有人使用以前共享的URL运行客户端,那么她的客户端不知道它应该调用的REST服务的URL,因为客户端无法构建URL-s,只需从REST服务接收并使用它。
例如:
http://my.client.com
http://my.api.com
获取根资源,并返回一个链接http://my.api.com/users
网址,其中包含rel用户集合http://my.client.com
更改为http://my.client.com/users
如果我们允许客户端从url:GET http://my.api.com/users
构建http://my.client.com/users
,则可以解决此问题,但这不会是RESTful,因为客户端不应构建api url。 ..
如果我想在客户端显示嵌套菜单,那么这是另一个问题,因为我不想在每个答案中发送整个菜单树。我可以为每个资源创建菜单投影,或使用OPTIONS方法或自定义方法发送该数据,但这将是一个痛苦的后面。这可以通过跟踪来自REST服务的rel=up
链接 - 串联来解决,但如果我不知道我应该从哪里开始,那么它将无法工作......
谷歌机器人也会出现此问题......
我如何解决这个问题,并保持在HATEOAS原则的范围内?
答案 0 :(得分:1)
通常我们不想与任何人分享所有这些信息,因此我们无法将所有这些信息仅导出到我们所在的当前页面。
将整个资源存储在客户端上然后将其推送到服务器以更改服务器上的状态没有任何问题。如果你担心你的资源变得太大了,你可以稍微分解一下资源。所以说你有一个订单资源,需要与一个地址相关联。您不需要将地址放在订单资源中,只需要指向要使用的地址的链接。用户可以单独添加或更改该地址。所以你可能会有像
这样的东西www.myapi.com/users/1234/shippingaddresses/default
客户端可以为此资源提供新地址。然后在订单资源的正文中,您可以拥有指向此资源的链接
POST www.myapi.com/users/1234/orders
{
...order information...
"shipping_address": "www.myapi.com/users/1234/shippingaddresses/default"
}
要成为RESTful,客户端不应该构建该URL,它应该是服务器在最近的某个时刻给出的,可能是在用户选择使用哪个地址时。例如,在上一步中,客户端可能已请求所有地址
GET www.myapi.com/users/1234/shippingaddresses
并在下拉列表中向用户显示地址列表。