web-dev-qa-db-fra.com

Comment filtrer les données de manière reposante avec Spring?

Comme le titre l'indique.

J'aimerais fondamentalement faire des demandes comme

/api/todos/?completed=eq.true&created_at=lt.1486462109399

Existe-t-il un spring way prêt à l'obtenir? Quelque chose qui ressemble au mécanisme page/page serait génial. 

S'il n'y en a pas, je pense que je pourrais l'implémenter en utilisant Hibernate Criteria Queries & Argol Re-Solvers. Cela me permet essentiellement d’écrire mes contrôleurs comme

 @GetMapping
 public ResponseEntity<Page<TodoDTO>> listAll(Criteria criteria, Pageable pageable) 
 {
        Page<Todo> todos = todoService.listAll(criteria, pageable)
        ...
 }

Un résolveur d’arguments personnalisé serait responsable de la conversion de la chaîne de requête en critères. Je ne sais pas encore comment je vais gérer cela au sein du service, mais c'est dans ce sens que j'essaierais de mettre cela en œuvre.

Serait-ce une bonne approche? Des recommandations? (Tous supposent qu’il n’existe déjà aucun mécanisme prêt à l'emploi).

Votre aide est tres apprecie.

9
Dawid

Une autre option permettant de créer une API de requête fluide consiste à utiliser un analyseur RSQL. RSQL est un langage de requête pour le filtrage paramétré des entrées dans les API RESTful. Suivez cet article et votre API serait capable de gérer des URL telles que:

http://localhost:8080/users?search=firstName==jo*;age<25

Contrôleur d'échantillon:

@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);
    }

}
3
naXa

Vous pouvez créer une API Search/Filter REST à l'aide de Spring Data JPA et Specifications . Voici un exemple d'URL de test que l'API obtenue pourrait gérer: 

http://localhost:8080/users?search=lastName:doe,age>25

et exemple de contrôleur:

@RestController
@RequestMapping(value = "/users")
public class UserController {

    @Autowired
    private UserRepository repo;

    @GetMapping
    public List<User> search(@RequestParam(value = "search") String search) {
        UserSpecificationsBuilder builder = new UserSpecificationsBuilder();
        Pattern pattern = Pattern.compile("(\w+?)(:|<|>)(\w+?),");
        Matcher matcher = pattern.matcher(search + ",");
        while (matcher.find()) {
            builder.with(matcher.group(1), matcher.group(2), matcher.group(3));
        }

        Specification<User> spec = builder.build();
        return repo.findAll(spec);
    }
}
3
naXa