GraphQl: entities eager-loaded but ignored (N+1 problem)
API Platform version(s) affected: 2.6.8, 3.0-rc2
Description
When querying collections with associations such as One to Many with GraphQl, extra requests are done (on per entity, N+1 problem) even if the eager loading is enabled. The query does include the correct JOIN, but the loaded entities are re-queried anyway.
How to reproduce
- Enable GraphQl.
- Create two entities (lets say Movie and Comments), and associate them in a way Move has many Comments.
- Query a collection of movies through GraphQl and the associated comments like so:
query {
movies {
edges {
node {
title
comments {
# In this example pagination has been disabled for comments
content
}
}
}
}
}
- Check the doctine queries on the symfony's profiler: you should have way to much query.
Possible Solution
I'm not sure where those extra queries are initiated, I think it might be when the query is executed field by field. It queries the necessary when processing the movies.edges.node field (with the comments eager loaded) and then continue. When executing the movies.edges.node.*.title.comments, it does it without checking if it has been hydrated on the parent already, and simply make a new query per parent (per movie).
I'm trying to get along with api-platform codebase by looking a lot at the internals, but I'm not familiar enough to debug completely and propose a PR.
Additional Context
This behavior is the same on the 3.0-rc2, all tested on a fresh project. I tried to tweak a lot of things with nomralization contexts, max depth, eager/lazy-loading, etc. Nothing worked for GraphQl (but did for REST api).