我在研究中碰到HATEOAS,当时在想:HATEOAS不会复制HTTP请求吗?
让我们以基本的customer
和order
为例。
假设您要检索订单,则端点为/orders/2
具有以下JSON响应:
{
"id": 2,
"total": 50.00,
"links": [{
"rel": "customer",
"href": "http://api.domain.com/customer/1
}]
}
现在如果我还需要客户该怎么办?我是否必须向/customer/1
发出另一个请求?这不会超载HTTP通信量吗?
我不能让customer
+ order
这对夫妻有一个像/customers/1/orders/2
这样的端点吗?
还是仅在customer
JSON响应中发送/orders/2
?
{
"id": 2,
"total": 50.00,
"customer": {
"id": 1,
"name": "Dylan Gauthier"
}
}
一种解决方案或另一种解决方案有什么好处?我何时需要一个或另一个?
谢谢! :-)
答案 0 :(得分:2)
如果服务器仅分别提供客户和订单,那么无论它们是否遵循REST,您都必须发出两个请求。
完全按照您的建议,关于REST或其HATEOAS约束的任何内容都不能阻止服务器在同一资源中同时提供客户和订单:
GET /orders/2
{
"id": 2,
"total": 50.00,
"customer": {
"name": "Dylan Gauthier"
}
}
但是该响应中的客户与标识符/customers/1
没有关系-服务器可以将这两种想法结合起来:
{
"id": 2,
"total": 50.00,
"links": [{
"rel": "customer",
"href": "http://api.domain.com/customer/1
}],
"resources": {
"http://api.domain.com/customer/1": {
"name": "Dylan Gauthier"
}
}
}
或更妙的是,按链接与请求资源的关系将其分组:
{
"id": 2,
"total": 50.00,
"links": {
"customer": [{
"href": "http://api.domain.com/customer/1"
}]
},
"resources": {
"http://api.domain.com/customer/1": {
"name": "Dylan Gauthier"
}
}
}
尽管这将使客户打印客户的名称需要做更多的工作(一点都不费力,介意),但如果客户愿意的话,它允许客户获取有关客户的更多信息!
答案 1 :(得分:0)
只需添加到Nicholas'答案中即可:
专家:为您节省前往服务器的旅程
缺点:虽然它可以为您节省第一次旅行,并且可能只有几行代码,但是您放弃了缓存:如果相关资源(您所嵌入的)客户端中的某些内容发生了变化缓存不再有效,因此客户端必须再次发出请求。当然,假设您利用HTTP缓存。你应该...
如果您想走这条路线,最好使用GraphQL之类的东西...但是请稍等!
优点:资源具有独立的生命周期;更容易使每种(类型)资源得到发展而又不影响其他资源。通过充分利用缓存和超时功能,整体性能会更好。
缺点:更多的请求(首次访问时),这在首次访问时可能会稍慢一些;一些更多的代码来管理HATEOS ...
我个人倾向于尽可能使用第二种方法。
经典的网络比喻:
如果可以帮助您,经典网站只是提供html相关资源的另一个API,客户端应用程序就是浏览器本身。如果您曾经做过一些html / css / js,则可能要采用相同的方法: 对于给定的特定网站,给定其导航体系结构... etc,您是否愿意在html页面(主要资源)中内嵌css / js(相关资源)的全部/部分。