问题。如何避免使用 Spring Data REST 进行 n+1 查询?
背景。在查询 Spring Data REST 以获取资源列表时,每个生成的顶级资源都具有指向关联资源的链接,而不是将关联资源直接嵌入顶级资源中。例如,如果我查询数据中心列表,相关区域会显示为链接,如下所示:
{
"links" : [ {
"rel" : "self",
"href" : "http://localhost:2112/api/datacenters/1"
}, {
"rel" : "datacenters.DataCenter.region",
"href" : "http://localhost:2112/api/datacenters/1/region"
} ],
"name" : "US East 1a",
"key" : "amazon-us-east-1a"
}
然而,想要获得相关信息而不需要进行 n+1 次查询是非常典型的。为了坚持上面的例子,我可能想在 UI 中显示数据中心及其相关区域的列表。
我试过的。我在 my 上创建了一个自定义查询,RegionRepository
以获取给定数据中心键集的所有区域:
@RestResource(path = "find-by-data-center-key-in")
Page<Region> findByDataCentersKeyIn(
@Param("key") Collection<String> keys,
Pageable pageable);
不幸的是,此查询生成的链接不会与上述数据中心查询生成的链接重叠。以下是我为自定义查询获得的链接:
http://localhost:2112/api/regions/search/find-by-data-center-key-in?key=amazon-us-east-1a&key=amazon-us-east-1b
{
"links" : [ ],
"content" : [ {
"links" : [ {
"rel" : "self",
"href" : "http://localhost:2112/api/regions/1"
}, {
"rel" : "regions.Region.datacenters",
"href" : "http://localhost:2112/api/regions/1/datacenters"
}, {
"rel" : "regions.Region.infrastructureprovider",
"href" : "http://localhost:2112/api/regions/1/infrastructureprovider"
} ],
"name" : "US East (N. Virginia)",
"key" : "amazon-us-east-1"
}, {
"links" : [ {
"rel" : "self",
"href" : "http://localhost:2112/api/regions/1"
}, {
"rel" : "regions.Region.datacenters",
"href" : "http://localhost:2112/api/regions/1/datacenters"
}, {
"rel" : "regions.Region.infrastructureprovider",
"href" : "http://localhost:2112/api/regions/1/infrastructureprovider"
} ],
"name" : "US East (N. Virginia)",
"key" : "amazon-us-east-1"
} ],
"page" : {
"size" : 20,
"totalElements" : 2,
"totalPages" : 1,
"number" : 1
}
}
挑战似乎在于,一旦您已经了解了数据的形状,数据中心查询返回的链接并不是特别有用。例如,我已经知道数据中心 1 的区域位于/datacenters/1/region
,所以如果我想了解涉及哪个特定区域的实际信息,我必须点击链接获取。特别是,我必须按照链接获取显示在批量查询中的规范 URI,这将允许我避免 n+1 查询。