Pour un de nos projets, nous construisons une API REST qui permet de récupérer des ressources de façon paginées. Les paramètres de la pagination sont standards : numéro de la page, nombre d’éléments par page et un paramètre de tri. Ces trois paramètres sont à répéter sur chacune de nos routes où nous souhaitons effectuer de la pagination, sauf qu’à chaque fois nous devons retrouver les différentes contraintes à appliquer notamment pour le paramètre de tri et cela a conduit à quelques différences entre les différentes routes, notamment au niveau du nom des paramètres (per_page, perPage ou limit pour le nombre d’éléments par page ?).
Nous allons voir comment faire pour passer de trois annotations à configurer à une seule, qui permettra d’éviter ce genre de différences. Une annotation pour les gouverner toutes !
Créer un Annotation Reader
Dans un premier temps, afin de pouvoir récupérer nos annotations et en faire quelque chose, nous devons créer notre Annotation Reader. Celui-ci a été inspiré de l’annotation reader de FOSRestBundle, la seule ligne changée est la ligne 51 qui vérifie qu’il s’agit d’une annotation nous appartenant, pour cela nous utilisons une interface ParamInterface nous appartenant.
Utiliser notre Annotation Reader au bon moment
Ensuite, il faut pouvoir ajouter nos annotations aux annotations que FOSRest parse déjà afin que le bundle fonctionne normalement. Notre code sert uniquement à compléter l’utilisation de FOSRest. Pour cela, nous allons construire un EventSubscriber qui va utiliser notre ParamReader et compléter le ParamFetcher de FOSRest avec les annotations que nous souhaitons construire.
Attention cependant, il faut que le ParamFetcher de FOSRest soit initlisé, nous devons donc interagir avec lui après que FOSRest l’ait initialisé. Une chance pour nous, le ParamFetcherListener de FOSRest est configuré avec une priorité à 5, nous pouvons attacher un event listener sans préciser sa priorité, qui sera à 0 par défaut et donc exécuté après. J’ai choisi un EventSubscriber afin de bénéficier de l’autoconfiguration des services Symfony.
GlobalParamFetcherSubscriber.php
Le subscriber ressemble assez à celui de FOSRest sauf que nous utilisons notre propre annotation reader (ligne 44) et c’est au moment de parcourir nos annotations que nous effectuons nos actions. La méthode getAnnotationsInstances retourne un tableau d’annotations que FOSRest sait traiter et que l’on ajoute à leur ParamFetcher.
Création de notre annotation personnalisée
Nous avons donc la logique qui existe et permet la récupération de nos annotations et de leur transformation en annotation que FOSRest sait utiliser. Il nous reste plus qu’à créer notre annotation qui englobe les paramètres de pagination.
La méthode importante est getAnnotationsInstances et c’est elle, combinée au subscriber précédent qui permet la transformation.
Conclusion
Il ne reste plus qu’à modifier notre code pour remplacer partout où nous avons utilisé nos paramètres de requête concernant la pagination par notre annotation.
L’utilisation avec le ParamFetcherInterface injecté dans le contrôleur reste identique, nous pouvons récupérer les paramètres avec $paramFetcher->get(‘_page’) par exemple.
Le point négatif étant que l’on n’ait plus clairement affiché au dessus de l’action le nom des différents paramètres concernant la pagination. Il est donc utile de constituer un chapitre de la documentation technique qui explicite ce point.
Si comme moi, vous avez des noms de paramètres hétérogènes d’une action à une autre, il suffit d’ajouter ceux-ci dans le PaginationParams et de modifier petit à petit les appels à l’api pour transmettre les nouveaux noms pour finir par supprimer ce petit ajout.
Voici un exemple avec le paramètre limit qui était utilisé auparavant, remplacé par le paramètre _per_page :
PaginationParamsWithLegacy.php