Filter query params in SpringBoot

96 views
Skip to first unread message

Lucio Benfante

unread,
Dec 21, 2023, 8:38:06 AM12/21/23
to jugp...@googlegroups.com
Ciao,
se qualcuno ha voglia, mi piacerebbe avere la vostra opinione su questo approccio che sto usando per ricevere query parameters in un controller Spring per implementare le funzionalità di filtro.

Il contesto iniziale è un piccolo progetto personale, che sto sviluppando con Enrico Giurin...ma questa è un'altra storia. Questa parte l'ho implementata come progetto separato, dato che intendo usarla anche in altri progetti.

L'approccio è simile al modo in cui in un'applicazione SpringBoot + Spring Data JPA e simili(ma Spring Data JPA non è obbligatorio, può essere usato anche senza, dato che è fornito da Spring Data Commons) vengono passati i parametri per la paginazione e l'ordinamento, aggiungendo un parametro di tipo Pageable al metodo di un controller. Qualcosa del genere:

@RestController
@RequestMapping("/people")
public class PeopleController {

    @Autowired
    private PeopleService peopleService;
    
    @GetMapping
    public List<Person> getPeople(Pageable pageable) {
        return peopleService.searchPeople(pageable);
    }
}

I query parameters page, size e sort vengono usati per costruire l'oggetto Pageable che verrà passato al metodo. Ovviamente la logica di paginazione sarà implementata nel service (o meglio, se usate Spring Data, nei repository che già supportano Pageable).

Tipicamente in una funzionalità del genere, oltre a paginazione e ordinamento, sarà necessario aggiungere anche dei parametri per filtrare i dati ritornati.

L'approccio che ho usato finora, e che è usato anche in praticamente tutti gli esempi che trovate in giro, è stato quello di aggiungere uno o più parametri per ricevere i valori con cui filtrare i dati, o altre informazioni se le necessità di filtro sono più complicate (operatori diversi, filtri multipli, combinati in maniera diversa, ecc. ecc.). Ottenendo quindi qualcosa del genere:

@GetMapping
public List<Person> getPeople(
        @RequestParam(required = false) String firstName,
        @RequestParam(required = false) String lastName,
        Pageable pageable) {
    return peopleService.searchPeople(firstName, lastName, pageable);
}

Ovviamente se il filtro può essere molto complicato, la signature del controller si complica di conseguenza, e la logica di recupero e passaggio di tali parametri può diventare altrettanto complicata, oltre ad essere ripetuta in tutti i controller che hanno bisogno di funzionalità simili.

Ho quindi provato a generalizzare la faccenda, introducendo il supporto per parametri di tipo Searchable:

@GetMapping
public List<Person> getPeople(Searchable searchable, Pageable pageable) {
    return peopleService.searchPeople(searchable, pageable);
}

Tale parametro viene costruito a partire da query parameters nella forma filter.<field>.value. Ad esempio, se arriva una richiesta tipo:


Al metodo del controller arriverà un oggetto Searchable contenente una proprietà conditions con una lista di oggetti come questa:

FilterCriteria [
    conditions=[
        FilterCondition [field=firstName, operator=containsIgnoreCase, value=John],
        FilterCondition [field=lastName, operator=containsIgnoreCase, value=Doe]
    ],
    combinator=AND]

Che ne pensate?


Qui trovate un esempio che lo utilizza: https://github.com/benfante/searchable-example

Spero lo troviate interessante, e aspetto suggerimenti e critiche.

A presto
  Lucio

-- 
Lucio Benfante
Java Professional
www.benfante.com
Reply all
Reply to author
Forward
0 new messages