Вопрос. Как избежать 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<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 запросов.