5
minutes
Mis à jour le
24/6/2024


Share this post

Ajoutez en 10 minutes une fonctionnalité de recherche avancée à votre API Spring Boot grâce à la bibliothèque spring search !

#
API
#
Spring Boot
#
Java
#
Open Source
#
REST
#
Filtre
#
Recherche
Vincent Escoffier
Software Engineer

Dans cet article, nous allons voir comment ajouter un endpoint à notre API Spring Boot 3 nous permettant de filtrer l’ensemble des champs d’une entité et de combiner les opérateurs logiques en utilisant les query parameters de l’URL. Voyez par exemple :

Il est très fréquent de devoir développer une fonctionnalité permettant de filtrer les données exposées par notre API. Imaginez que vous développez une API pour un site de vente de voitures. Les utilisateurs ne sont pas intéressés par toutes les voitures, mais seulement par celles qui correspondent à leurs critères, tels que la marque, le modèle, le kilométrage, le prix, etc. Vous pouvez commencer par définir plusieurs endpoints sur votre API pour permettre de filtrer chaque champs. Cependant, plus votre modèle de données grandit, plus il devient compliqué de couvrir l'ensemble des cas d'usage et votre code gérant la recherche peut devenir de plus en plus complexe à faire évoluer. De plus, vous ne pouvez pas connaître à l’avance toutes les recherches qui pourraient intéresser vos utilisateurs et souhaitez vous offrir une certaine flexibilité.

Dans notre cas, nous aimerions pouvoir permettre au client de générer une représentation contenant à peu près n'importe quel sous-ensemble de données selon les filtres qu'il souhaite, et cela sans avoir à modifier notre code à chaque changement du modèle !

Plusieurs aspects sont à prendre en compte pour la mise en place d’un tel pattern :

  • Définition d’un Domain Specific Language permettant d'exprimer la requête (opérateurs, syntaxe, etc.), pensez par exemple au langage de recherche de Github.
  • Parsing de la requête, pour la convertir en un objet manipulable par votre backend, par exemple par l’intermédiaire d’un AST.
  • Filtrage des données, transformation de l’AST en une requête SQL, une pipeline Mongo, etc..

Tout implémenter from scratch nécessite une quantité de code non négligeable qu’il faudra ensuite maintenir et tester. Nous allons voir dans cet article comment adopter ce pattern avec la bibliothèque Spring Search. A la fin de cet article, nous aurons un endpoint nous permettant de filtrer l’ensemble des champs de notre entité et de combiner les opérateurs logiques, et tout cela grâce une simple annotation dans notre controller !

⚠️ Gardez à l'esprit qu'implémenter un tel système de filtres peut se retourner contre vous ! Vous donnez toute la liberté à l'utilisateur de faire des requêtes complexes, alambiquées et potentiellement coûteuses pour votre API. Il est également très difficile d’implémenter un système de cache car les combinaisons sont potentiellement illimitées. Dans le cas où un nombre raisonnable d'endpoints vous permettrait de couvrir l'ensemble des cas d'usage, il est souvent préférable d'avoir des endpoints prédéfinis, optimisées en termes de performances et répondant à un cas d’usage précis. Je vous invite à consulter cet article pour en savoir plus sur les inconvénients de ce pattern.

Place à la pratique : Spring Search

Prenons comme référence l’entité suivante :

Nous allons dans cet article ajouter une route sur notre API nous permettant de filtrer nos voitures 🚕 !

  • Commençons par ajouter la dépendance spring-search, la bibliothèque est compatible avec spring-boot 3.X.
  • Ajoutons ensuite une classe de @Configuration pour enregistrer notre resolver
  • Ajoutons également un repository annoté avec RepositoryRestResource et héritant de JpaSpecificationExecutor
  • Nous n’avons finalement plus qu’à utiliser l’annotation SearchSpec dans notre controller

Et c’est tout ! Vous pouvez maintenant interroger le endpoint suivant pour tester notre nouvelle route 🙂.

De nombreux opérateurs sont disponibles, tel que égal, supérieur, inférieur, ET/OU logiques, etc. Vous pouvez trouver la liste complète ici.

Pour retrouver le code de l’article, c’est ici.

Conclusion

Plutôt que de développer et de maintenir une grande quantité de code spécifique pour chaque filtre et chaque entité, vous pouvez ajouter une fonctionnalité de recherche complète à votre API grâce à une simple annotation dans votre controller.

Pour plus d’informations, n’hésitez pas à consulter le code source de spring-search, ainsi qu’à contribuer !