Query by Example doesn't have a binding customization mechanism
I have a GraphQLRepository that extends QueryByExampleExectutor
@GraphQlRepository
public interface BookRepository extends JpaRepository<Book, Long>, QueryByExampleExecutor<Book> {}
If I try to do a partial match on the book title no results come back. If I enter the full book title the results come back as expected.
// Find books by partial title match
query {
books(book: { title: "Spring Boot" }) {
id
title
author
publishedYear
}
}
I realize I can write a data fetcher for this but this:
@Controller
public class BookController {
private final BookRepository repository;
public BookController(BookRepository repository) {
this.repository = repository;
}
@QueryMapping
public List<Book> booksContaining(@Argument(name = "book") Book filterBook) {
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
.withIgnoreCase()
.withIgnoreNullValues();
Example<Book> example = Example.of(filterBook, matcher);
return repository.findAll(example);
}
}
But I would like a way to customize this so I can use a StringMatcher.CONTAINING and match on part of the book title.
Customizing ExampleMatcher is a reasonable request. Introducing a strategy interface that creates ExampleMatcher would be my initial approach. I'm not quite sure about the context that we should provide to the method. I think something along the lines for an initial cut:
interface ExampleMatcherProvider<T> {
ExampleMatcher getExampleMatcher(T probe, DataFetchingEnvironment environment);
}
Such a signature would provide the most meaningful context.
For auto-registration, I think a programming model to let repositories implement the interface through a default method would be neat:
@GraphQlRepository
public interface BookRepository extends JpaRepository<Book, Long>,
QueryByExampleExecutor<Book>, ExampleMatcherProvider<Book> {
default ExampleMatcher getExampleMatcher(Book probe, DataFetchingEnvironment environment) {
return …;
}
}
Alternatively, defining a @Bean ExampleMatcherProvider<Book> and using ResolvableType to correlate the strategy object could work too.
We've been regularly trying to come up with a good model to express customization approaches. Query by Example is much more constrained than Querydsl and so a reduced functionality scope could allow a more declarative approach.
However, there is very little demand and so we do not have a good amount of usecases to determine commonalities. Therefore, we're closing this ticket for the time being. We want to come back to it once there is more substance we can learn from to come up with an approach that is useful to users.