Comment récupérer toutes les informations concernant une collection d’objets via l’API Strapi ?

Contexte

Strapi, c’est un outil qui permet de créer très simplement une API, que ce soit REST ou GraphQL.
C’est une solution Française, c’est open source, il y a beaucoup d’options, de plugins possibles etc…
Il gère aussi bien les images que la possibilité d’ajouter des composants personnalisés.

Pour tout gérer, on a accès à une interface admin.

Problème - Récupérer les images d'un objet

Le premier souci que j’ai eu, c’est que lorsque je récupère les données API d’un objet contenant une image par exemple, par défaut il ne renvoie pas d’information concernant les images.

Solution - Récupérer les images d'un objet

Par défaut, Strapi récupère seulement les informations concernant la collection de l’objet en question.
Par exemple, si on veut récupérer les articles, il va transmettre toutes les informations concernant la collection « Article » et seulement la collection « Article ».

C’est quoi le problème alors ? Pourquoi les images ça ne fonctionne pas par défaut ?
Eh bien.. Parce que c’est gérer par « Upload ».
Les objets articles sont gérés en fonction de la collection « Article » et les images sont par défaut gérer par la collection « Upload ».
Pour passer outre ce problème, il faut utiliser « populate » de Strapi, comme ceci par exemple :

http://localhost:1337/api/articles?populate=cover

Pourquoi « cover » ? Eh bien, parce que dans mon content-type, mon objet Article ressemble à ça, c’est celui par défaut à titre d’exemple.
/!\ Modifiez donc la valeur de populate en fonction de votre besoin !

Grâce à « populate », on peut lui demander de recherches les éléments de différentes collections.

Problème - Gérer plusieurs champs sur une collection

Mais… et si dans ma collection « Article », j’ai besoin de récupérer plusieurs champs ?? Par champ « Média » nommé ici « cover », mais également le champ « Relation avec Category » nommé « category », comment je fais ??

Solution - Gérer plusieurs champs sur une collection

Il existe plusieurs options :

Solution 1

Brutale, mais efficace :

http://localhost:1337/api/articles?populate=*

Elle récupère absolument tout d’un coup, ce n’est pas forcément le plus optimisé mais en fonction de vos besoins ça peut être très utile.

Solution 2

Plus douce, potentiellement plus optimisée mais nécessite de faire attention en mettant à jour les valeurs de « populate » si nécessaire :

http://localhost:1337/api/articles?populate=cover&populate=category

Problème - Gérer les champs "Dynamic zone"

Par défaut, même avec la méthode forte, c’est à dire « populate=* », on ne récupère pas toutes les informations sur les composants.
Il en va de même si on fait juste « populate=blocks ».
Sur les composants « rich-text », on reçois le body, mais pour les composants « media », rien mis à part l’id.

Solution - Gérer les champs "Dynamic zone"

D’après l’IA de leur documentation, « Lorsque vous utilisez populate=* avec une dynamic zone, cela ne peuple que le premier niveau des composants, sans inclure les relations ou médias plus profonds. ».
Dis avec mes mots, par défaut Strapi ne récupère pas les  « objets des objets ».
Pour ce faire, il faut lui demander explicitement de récupérer les informations de chacun des composants.

À ma connaissance, on a plus vraiment le choix que de passer par la « méthode douce » :

http://localhost:1337/api/articles?populate[blocks][on][shared.media][populate]=*&populate=cover

Par contre, les URLs comme ça à rallonge, entre nous c’est assez chiant.
En React, avec Axios, on peut faire quelque chose dans ce genre là par exemple :

import axios from "axios";

export const fetchArticles = async () => {
  try {
    const response = await axios.get('http://localhost:1337/api/articles', {
      params: {
        'populate[blocks][on][shared.media][populate]': '*',
        populate: 'cover',
      },
    });

    return response.data;
  } catch (error) {
    console.error('Error fetching articles:', error);
    throw error;
  }
};

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *