我从实用的角度阅读了很多文章和很多Apigee文档和设计RESTful API的最佳实践。但我不能完全理解的一件事是,为API的消费者构建设施是否可选地在同一文档中包含其他资源是好还是坏。
我的直觉是,通常应避免以下情况: -
/accounts?include=transactions
{ accounts: [
{ "id": "101",
...
"transactions": [ ... ]
},...
最好不要: -
/accounts
{ accounts: [
{ "id": "101",
...
"transactions": /link/to/transactions/for/acccount
},...
然后
/transactions
{ "transactions": [
{ "id": ...
我并不担心遵守REST的纯粹主义原则,例如。 HATEOS等我采取这种观点的主要原因是: -
/transactions
加载到我的/accounts
中意味着这会引入提供API的服务组件之间的耦合 - 这与架构(Monolith或微服务)无关。这是一个公平的论据/方法吗?
答案 0 :(得分:0)
您可能还想查看sidecar embedding。
我不能完全理解的一件事是,为API的消费者构建设施是否可选地在同一文档中包含其他资源是好还是坏。
嗯,这可能不是其中之一。它可能适合或不适合您的使用案例,但在正确的设置中可能是相反的情况。
也就是说,如果你在考虑REST,那么看看参考实现(WWW)的作用就不会有什么坏处。网络上占主导地位的超媒体类型是HTML;你有代表,并链接到辅助表示,但绝对没有模拟“这里是这个文件链接到的东西的表示,以防万一”。
换句话说,有一个已经建立的,非常成功的先例,即“链接到一切,让缓存解决”。自己wrote
查询结果由带有摘要信息的链接列表表示,而不是由对象表示数组表示(查询不能代替资源标识)。
另一个折衷方案是支持两种资源;带链接的配对版本,以及带有嵌入数据的丰富版本。 GetEventStore有这种模式,有三种不同的资源
http://127.0.0.1:2113/streams/newstream2
vs
http://127.0.0.1:2113/streams/newstream2?embed=rich
vs
http://127.0.0.1:2113/streams/newstream2?embed=body
您可以提供两种陈述的链接,让您的客户选择最适合他们情况的那些;或者(如果您使用的是HATEOAS),您可以控制哪些链接关系出现在哪些表示中。
(另一种可能性是拥有一个资源,但每个表示都有一个单独的媒体类型)。
您可能还需要考虑负责修改域模型的“聚合”资源可能与支持查询的许多“投影”资源不同,但不做任何修改。这是CQRS方法。
Jim Webber:“您应该希望集成域中的资源比业务域中的业务对象多得多。”