Strapi v4 : Comment personnaliser le retour des apis

Introduction

Strapi, un framework open-source basé sur Node.js, simplifie le processus de création d’API REST robustes. Dans ce guide, nous allons etudier comment configurer Strapi pour qu’il retourne automatiquement toutes les informations nécessaires, y compris les relations, pour un Content Type particulier, en utilisant un exemple concret avec deux entités : “Menu” et “Menu item”.

Prérequis

Avant de commencer, assurez-vous d’avoir installé Node.js et yarn. Vous pouvez installer Strapi globalement avec la commande suivante :

yarn create strapi-app my-project --ts --quickstart

Création des Content Types

Nous allons créer deux Content Types : “Menu” et “Menu item” puis les remplir avec des données de tests.

Menu item

Commençons par le content-type Menu item qui doit être configuré comme suit :

  • Field: name, Type: string ou text short
  • Field: link, Type: string ou text short
  • Field: position, Type: number
yarn strapi generate content-type

#Répondez de la manière suivante :
Content type display name : Menu item
Content type singular name : menu-item
Content type plural name : menu-items
Please choose the model type Collection : Type
Use draft and publish? No
Do you want to add attributes? Yes
Name of attribute : name
What type of attribute : string
Do you want to add another attribute? Yes
Name of attribute : link
What type of attribute : string
Do you want to add another attribute? Yes
Name of attribute : position
What type of attribute : integer
Do you want to add another attribute? No
Where do you want to add this model? Add model to new API
Name of the new API? menu-item
Bootstrap API related files? Yes
✔  ++ /api/menu-item/content-types/menu-item/schema.json
✔  +- /api/menu-item/content-types/menu-item/schema.json
✔  ++ /api/menu-item/controllers/menu-item.ts
✔  ++ /api/menu-item/services/menu-item.ts
✔  ++ /api/menu-item/routes/menu-item.ts

Menu

Pour le content-type Menu nous aurons les champs ci-dessous :

  • Field: name, Type: string ou text short
  • Relation: Menu item, Type: Belong to many

Le type de relation n’étant pas disponible en ligne de commande nous allons créer le content-type en ligne de commande puis ajouter la relation via l’administration de strapi.

yarn strapi generate content-type

#Répondez de la manière suivante :
Content type display name : Menu
Content type singular name : menu
Content type plural name : menus
Please choose the model type : Collection Type
Use draft and publish? No
Do you want to add attributes? Yes
Name of attribute : name
What type of attribute : text
Do you want to add another attribute? No
Where do you want to add this model? Add model to new API
Name of the new API? menu
Bootstrap API related files? Yes
✔  ++ /api/menu/content-types/menu/schema.json
✔  +- /api/menu/content-types/menu/schema.json
✔  ++ /api/menu/controllers/menu.ts
✔  ++ /api/menu/services/menu.ts
✔  ++ /api/menu/routes/menu.ts

Se rendre sur le menu “Content-type Builder” > “Menu” afin d’ajouter un nouveau champs de type relation :

Remplissage des données

Ajoutons quelques données à nos entités depuis l’administrant strapi en créant une entrée dans le Content Type “Menu” que nous nommerons “Menu principal”. Puis, créons des sous-menus que nous nommerons “Page d’accueil” et “Contactez-nous”. N’oublions pas d’affecter ces sous-menus à notre menu principal, établissant ainsi les relations nécessaires pour une hiérarchie fonctionnelle.

// Menu
{
  "name": "Menu principal"
}

//Menu items
 {
   "name": "Page d'accueil",
   "link": "/homepage",
   "position": 1
 }

{
  "name": "Contactez-nous",
  "link": "/contact-us",
  "position": 2
}

Configurer les permissions

Pour configurer les permissions d’accès, suivez ces étapes :

  1. Accédez à la section “Settings” > “Roles” > “public”.
  2. Assurez-vous que dans la section “Menu” et “Menu item”, les autorisations “find” et “findOne” sont correctement sélectionnées.

Ces autorisations permettront à votre API de répondre efficacement aux requêtes de type find et findOne pour les entités Menu et Menu item, garantissant ainsi l’accès approprié aux informations pour les utilisateurs publics.

Création du Middleware

Nous allons créer un middleware qui sera appelé lors de la recherche d’un menu. Ce middleware forcera la requête à inclure toutes les relations pertinentes. Utilisez la commande suivante pour générer le middleware :

yarn strapi generate middleware menu-relations

#Répondez de la manière suivante :
Middleware name : menu-relations
Where do you want to add this middleware? Add middleware to an existing API
Which API is this for? menu
✔  ++ /api/menu/middlewares/menu-relations.ts

Dans le fichier généré (src/api/menu/middlewares/menu-relations.ts), ajoutez le code suivant :

import { Strapi } from '@strapi/strapi';

export default (config, { strapi }: { strapi: Strapi }) => {
  return async (ctx, next) => {
    
    const populate = {
      menu_items: {
        sort: ['position:asc'],
        fields: ['name', 'link', 'position'],
      }
    };
    
    ctx.query.populate = populate
    await next();
  };
};

Cette logique simple utilise populate pour inclure automatiquement dans la requête les relations du Content Type “Menu” et le trie des Menu items en fonction du champs position.

Si vous souhaitez offrir à l’utilisateur la flexibilité de personnaliser le retour de l’API, vous avez la possibilité de remplacer la ligne 13 du fichier menu-relations.ts par le code suivant :

ctx.query = { 
  populate, 
  ...ctx.query 
}

Cette modification permet à l’utilisateur de spécifier ses propres paramètres de requête tout en incluant les options de population. Les paramètres de l’utilisateur écraserons les paramètres prédéfinis pour une même propriété existante dans les deux tableaux. Ainsi, cette approche offre une personnalisation totale du retour de l’API en permettant à l’utilisateur de définir des filtres, des tris, ou d’autres paramètres de requête selon ses besoins, tout en conservant la fonctionnalité de personnalisation de notre api.

Une alternative qui peut également être envisagée comme une mesure de sécurité consiste à inverser les positions de ctx.query et populate, de manière à ce que les propriétés par defaut (populate) écrasent éventuellement celles qui pourraient exister dans ctx.query avec la valeur fournie par l’utilisateur en dernier, cela permet d’exercer un contrôle plus rigoureux sur les données incluses dans la réponse de l’API.

ctx.query = {
  ...ctx.query,
  populate
};

Cette approche pourrait être particulièrement pertinente dans des cas d’utilisation spécifiques, tels que la nécessité de retourner exclusivement les données créées par l’utilisateur actuel. En permettant à l’option de population (populate) de prévaloir sur les éventuelles propriétés présentes dans ctx.query, on offre une flexibilité accrue pour filtrer et personnaliser les résultats de manière sécurisée.

Configuration du Middleware

Pour configurer notre middleware nous aurons besoin de son nom system, pou ce faire exécuter la commande ci-dessous puis :

yarn strapi middlewares:list

Ouvrez le fichier src/api/menu/routes/menu.ts et configurez le middleware pour être appelé lors de l’invocation de notre api. Ajoutez le middleware à la route find comme suit :

import { factories } from '@strapi/strapi';

export default factories.createCoreRouter('api::menu.menu', {
    config: {
        find: {
            middlewares: ['api::menu.menu-relations'],
        }
    },
});

Tout commence lorsque le serveur Strapi reçoit une requête HTTP de l’utilisateur. Cette requête peut être une opération de lecture (GET), d’écriture (POST, PUT, PATCH), ou de suppression (DELETE). Le middleware global intervient juste après la réception de la requête. Il offre une opportunité d’effectuer des actions spécifiques avant que la requête n’atteigne le contrôleur. Cela peut inclure des vérifications de sécurité, la transformation de données, l’ajout d’en-têtes personnalisés, etc. Dans ce guide nous avons mise en place une Route Middleware.

Tester

Utilisez postman ou exécutez la commande ci dessous dans un terminal

curl http://localhost:1337/api/menus

Résultats :

{
    "data": [
        {
            "id": 1,
            "attributes": {
                "name": "Menu principal",
                "createdAt": "2024-01-14T12:56:49.450Z",
                "updatedAt": "2024-01-14T12:56:49.450Z",
                "menu_items": {
                    "data": [
                        {
                            "id": 1,
                            "attributes": {
                                "position": 1,
                                "name": "Page d'accueil",
                                "link": "/homepage"
                            }
                        },
                        {
                            "id": 2,
                            "attributes": {
                                "position": 2,
                                "name": "Contactez-nous",
                                "link": "/contact-us"
                            }
                        }
                    ]
                }
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pageSize": 25,
            "pageCount": 1,
            "total": 1
        }
    }
}

Conclusion

Avec ces étapes simples, vous avez configuré Strapi pour retourner automatiquement les relations pertinentes lors de l’accès à un Content Type spécifique via API. Ce processus vous permet de simplifier la récupération des données côté client en évitant des requêtes multiples.

Mamadou Diagne
Mamadou Diagne
Architecte logiciel & CTO

Diplômé d'ETNA, la filière d'alternance d'Epitech, j'ai acquis une expertise solide dans le développement d'applications, travaillant sur des projets complexes et techniquement diversifiés. Mon expérience englobe l'utilisation de divers frameworks et langages, notamment Symfony, Api Platform, Drupal, Zend, React Native, Angular, Vue.js, Shell, Pro*C...

0 0 votes
Évaluation de l'article
guest
0 Commentaires
Commentaires en ligne
Afficher tous les commentaires

Ingénierie informatique (SSII)

Applize crée des logiciels métiers pour accompagner les entreprises dans la transition vers le zéro papier.


Avez-vous un projet en tête ? Discutons-en.