10 janvier 2023
Strapi v4 : Les nouveautés du CMS headless
4 minutes de lecture
En 2021 Premier Octet lançait son premier projet avec Strapi, (retrouvez le premier article de Vincent ici). 1 an et demi plus tard place à la v4 pour un nouveau projet. L’occasion de faire un tour d’horizon des nouvelles fonctionnalités sorties depuis sur ce CMS headless modulable.
Le support TypeScript enfin disponible ! 🎉
Largement attendu sur la v4, TypeScript est maintenant compatible avec Strapi, rendant l’expérience de customisation du backend bien plus agréable. La commande d’initialisation du projet prend un argument supplémentaire :
yarn create strapi-app my-project --ts
Avec les fichiers .ts les types de la classe Strapi sont disponibles via un simple import
import { Strapi } from '@strapi/strapi'
l’ensemble des méthodes devient alors accessible via l’autocomplete 👏. La génération des types se fait ensuite en lançant
yarn strapi ts:generate-types
qui crée automatiquement le fichier schemas.d.ts à la racine du projet.
La recherche améliorée en bdd
La montée en puissance de cette v4 se voit essentiellement sur l’évolution du système de query de la base de données. La syntaxe de l’API change légèrement, 'db.query()' cible le modèle voulu grâce à un uid au format suivant
api::nom-de-l-api.nom-du-content-type
Nous utiliserons ici l’api query engine pour illustrer les changements qui lui ont été appliqués. Cependant, pour interagir avec la base de données Strapi recommande l’usage de l’API Entity Service capable de gérer les structures de données plus complexes comme les composants ou les zones dynamiques.
Filtres
Les filtres peuvent être passés directement à la méthode findMany
sous forme d’objet. Un format plus lisible notamment lorsque l’on combine plusieurs conditions :
const entries = await strapi.db.query('api::article.article').findMany({
where: {
$and: [
{
title: 'Hello World',
},
{
createdAt: { $gt: '2021-11-17T14:28:25.843Z' },
},
],
},
},
});
Relations
Le query engine permet aussi de peupler les relations de manière beaucoup plus fine qu’auparavant en passant les champs requis sous forme d’objet. On peut ainsi appliquer des filtres ou une logique de sélection spécifique au sein même des relations :
strapi.db.query('api::article.article').findMany({
populate: {
relationA: {
where: {
name: {
$contains: 'Strapi',
},
},
},
},
})
Tri
De la même façon, le paramètre orderBy
accepte lui aussi un objet et rend le tri sur la base de champs relationnels simple comme bonjour :
strapi.db.query('api::article.article').findMany({
orderBy: {
author: {
name: 'asc',
},
},
})
Pagination
La v4 ajoute aussi la possibilité de paginer les résultats. Les API REST et GRAPHQL prennent des paramètres supplémentaire pagination[page]
et pagination[pageSize]
(ou pagination[start]
et pagination[limit]
pour une pagination en offset) :
?pagination[page]=1&pagination[pageSize]=10
Le format des données évolue lui aussi un peu. Les champs de chaque item sont maintenant regroupés sous la propriété “attributes”, distinct de la propriété “meta” contenant notamment les infos de pagination :
{
"data": [
{
"id": 1,
"attributes": {
"title": "Chaise Design",
"description": "Description Chaise Design"
},
"meta": {
"availableLocales": []
}
// ...
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 10,
"pageCount": 3,
"total": 28
}
}
}
Gestion des erreurs
La gestion des erreurs se simplifie sur Strapi v4. L’objet de contexte ctx, accessible dans les middleware et controllers, dispose maintenant de toutes les fonctions d’erreur associées aux codes http classiques. Ces fonctions prennent en paramètre :
- un message
- et un objet correspondant à la clé details dans le corps du message d’erreur renvoyé
if (!newName) {
return ctx.badRequest('le nom est manquant, { foo: 'bar' })
}
Concernant la protection des routes, on note aussi la possibilité de définir des Token d’accès à l’API de Contenu (maintenant totalement distincte de l’API d’Admin) directement depuis les settings de l’app.
L’API Plugin et Le Design System : le combo gagnant pour une intégration parfaite
Côté plugins l’API dédiée a aussi changé. Sur la v3 la création de plugin nécessitait une structure de fichiers spécifique et inaltérable. Sous la v4 la commande de génération des plugins ne créée plus que 2 dossiers : On conserve Admin pour tous les éléments frontend du plugin, tous les éléments du back sont eux regroupés dans Server :
On gagne aussi largement en flexibilité puisque seulement 2 fichiers à la racine du plugin sont réellement obligatoires :
strapi-server.js
pour initialiser le serverstrapi-admin.js
pour la partie front
Sur l’UI, pour assurer une intégration optimale des plugins à l’application, Strapi rend accessible tous ses composants dans son nouveau Design system 🎁. Une collection complète qui permet de gagner du temps sur le design et d’obtenir un résultat vraiment propre.
Et comme ils sont vraiment bien organisés chez Strapi, on retrouve l’ensemble des infos sur la création de plugins ainsi que leurs tutoriels (articles ou vidéo) sur une seule page bien rangée et documentée.
On ne peut pas avoir le beurre et l’argent du beurre : les plugins v3 et v4 ne sont malheureusement pas compatibles ! Mais avec plus de 90 plugins v4 disponibles sur la market place vous pourriez bien y trouver votre bonheur.
Les custom fields
Créer des plugins facilement c’est bien, pouvoir les utiliser dans les champs de nos modèles c’est encore mieux. Et c’est le cas avec les nouveaux custom fields. Besoin d’un champ color picker, ou d’une localisation sur une carte ? Les champs sur la création et l’édition de contenu s'enrichissent :
Les Extras
Changements plus minimes mais toujours agréables, on notera aussi dans cette nouvelle mouture
- l’arrivée du dark mode sur l’app
- et l’intégration de la market place Strapi dans le menu administrateur au lieu d’un simple lien vers la version web
Bref vous l'aurez compris, cette v4 peaufine la flexibilité d'un CMS headless qui possédait déjà de nombreuses qualités. Chez Premier Octet ce n'est pas notre premier projet avec Strapi et avec toutes ces nouveautés, ça ne sera sûrement pas le dernier !