Nested Filtering using basic Middleware
kwstnr opened this issue · 2 comments
Product
Hot Chocolate
Version
14.0.0.
Link to minimal reproduction
https://github.com/kwstnr/HotChocolateFilteringPrototype
Steps to reproduce
- Clone Repository
- Run
docker-compose up
- start api
- run following queries in Nitro/BananaCakePop
query BooksIQueryable {
booksIQueryable(where: { author: { name: { eq: "Author 1"}}}) {
id
title
author {
id
name
}
}
}
query BooksInMemoryQueryable {
booksInMemoryQueryable(where: { author: { name: { eq: "Author 1"}}}) {
id
title
author {
id
name
}
}
}
query BooksInMemoryEnumerable {
booksInMemoryEnumerable(where: { author: { name: { eq: "Author 1"}}}) {
id
title
author {
id
name
}
}
}
What is expected?
As you can see, only the BooksIQueryable
query returns a list of books for which the filtering applies. The other queries don't return any books at all, however, if you set breakpoints in the queries, you can see, that the query function returns a list of books but the filtering middleware filters them out.
What is actually happening?
According to this documentation I would expect the filtering middleware to be able to handle either IQueryable<T>
and IEnumerable<T>
types and it does when using basic filtering, but as soon as nested filtering is involved, only the query which returns a IQueryable
from EFCore works. Even when you decide to go with in memory filtering, using asQueryable()
or directly returning a IEnumerable<T>
I would expect the filtering middleware to work.
Relevant log output
No response
Additional context
Maybe I don't understand the filtering middleware good enough but according to the documentation I would expect it to work this way.
@michaelstaib so this means that filtering is always applied before the resolvers of the requested node?
It makes perfect sense to not resolve unnecessary properties of objects which are filtered out!
However, how would you suggest filtering for properties which are resolved after the filtering would be applied? If I follow your courses on dometrain, you suggest to use DataLoaders to efficiently resolve dependent, nested objects, like an author of a book in this case. This makes total sense in terms of querying your database efficiently, but what happens if you want to filter a list of books by their author, as it is depicted in my reproduction repository?
If you look at the latest commit, you can see that I added a DataLoader to resolve authors of books. Now if you want to apply the aforementioned filtering, you have to include the authors in the books query and then resolve them again for each book using the DataLoaders.
Is it expected that the authors are always materialized in the books query and are manually added to the DataLoader cache so that they are not requested twice from the db, or is there a way to apply filtering after all the requested properties are resolved?