As the title says.
I basically would love to do requests like
/api/todos/?completed=eq.true&created_at=lt.1486462109399
Is there any ready spring way
of achieving such? Something akin to the Page/Pageable mechanism would be great.
If there is none I think I could implement it using Hibernate Criteria Queries & Argument Re-solvers. Basically allowing me to write my controllers like
@GetMapping public ResponseEntity<Page<TodoDTO>> listAll(Criteria criteria, Pageable pageable) { Page<Todo> todos = todoService.listAll(criteria, pageable) ... }
A custom Argument resolver would be responsible for turning the query string into a Criteria. Not quite sure yet how I would handle it within the service but that’s the direction in which I would try to implement this.
Would that be a good approach? Any recommendations? (All assuming there are no ready mechanism for such already).
Your help is much appreciated.
Advertisement
Answer
Another option to build a fluent query API is to use a RSQL parser. RSQL is a query language for parametrized filtering of entries in RESTful APIs. Follow this article and your API would be able to handle URLs like:
http://localhost:8080/users?search=firstName==jo*;age<25
Sample controller:
@RestController @RequestMapping(value = "/users") public class UserController { @Autowired private UserRepository repo; @GetMapping public List<User> findAllByRsql(@RequestParam(value = "search") String search) { Node rootNode = new RSQLParser().parse(search); Specification<User> spec = rootNode.accept(new CustomRsqlVisitor<User>()); return repo.findAll(spec); } }
Gradle dependency:
// https://mvnrepository.com/artifact/cz.jirutka.rsql/rsql-parser implementation("cz.jirutka.rsql:rsql-parser:2.1.0")
Recommendations from the library author:
I recommend to use separate URI query parameter for sorting, e.g.
?query=name==Flynn&sortBy=name
, not to mix it with RSQL expression. The same applies to paging; I recommend URI parameters namedlimit
andoffset
.