Как избежать n + 1 запросов с помощью Spring Data Rest?
Вопрос. Как избежать n + 1 запросов с Spring Data REST?
Фон. При запросе 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 запросов. Чтобы придерживаться приведенного выше примера, я мог бы хотеть отобразить список центров обработки данных и связанных с ними областей в пользовательском интерфейсе.
Что я'мы пробовали Я создал собственный запрос на моемRegionRepository
чтобы получить все регионы для заданного набора ключей центра обработки данных:
@RestResource(path = "find-by-data-center-key-in")
Page findByDataCentersKeyIn(
@Param("key") Collection keys,
Pageable pageable);
К сожалению, ссылки, генерируемые этим запросом, неt перекрываются со ссылками, которые генерирует вышеупомянутый запрос центра обработки данных. Вот ссылки, которые я получаю для пользовательского запроса:
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 запросов.