Client TypeScript typé pour l’OpenAPI de Strapi 5 dans Next.js
Apprenez pas à pas à exporter la spécification OpenAPI de Strapi 5, générer un client TypeScript typé avec swagger‑typescript‑api, et l’intégrer dans un projet Next.js 13 (React 18, Node 20) avec Axios et SWR.
Par l’équipe Revisionary · · 4 min de lecture
Strapi 5 peut émettre une spécification OpenAPI 3.1 pour son Content API. En la transmettant à swagger‑typescript‑api, vous obtenez un client TypeScript entièrement typé qui fonctionne immédiatement avec Axios. Ce guide montre comment générer la spécification, créer le client et l’utiliser dans une application Next.js 13 construite avec React 18, Node 20, TypeScript 5, SWR et une gestion des requêtes compatible server‑action.
1. Exporter la spécification OpenAPI depuis Strapi
Strapi inclut une commande CLI expérimentale qui écrit un document JSON OpenAPI.
# Depuis la racine du projet Strapi
yarn strapi openapi generate --output ./docs/api-spec.jsonyarn strapi openapi generateest la commande officielle (voir la documentation CLI de Strapi).--outputvous permet de placer le fichier où votre dépôt front‑end pourra le lire. Le fichier généré contient toutes les routes CRUD, les routes personnalisées, les points d’authentification et les extensions de plugins. Un en‑tête typique ressemble à ceci :
{
"openapi": "3.1.0",
"x-powered-by": "strapi",
"x-strapi-version": "5.21.0",
"info": {
"title": "My Strapi API",
"version": "1.0.0"
}
}2. Ajouter le générateur à votre dépôt front‑end
Dans le projet Next.js, installez le générateur et ses dépendances peer.
npm install swagger-typescript-api axios swr js-cookie
# ou avec yarn
yarn add swagger-typescript-api axios swr js-cookieCréez un script qui lance le générateur sur le fichier de spécification.
// package.json
{
"scripts": {
"generate:api": "swagger-typescript-api generate --path ./docs/api-spec.json --output ./src/api --axios"
}
}Lancer npm run generate:api (ou yarn generate:api) produit un dossier src/api contenant deux artefacts principaux :
api.ts– une classeApiqui enveloppe une AxiosInstance pré‑configurée avec l’URL de base et des signatures de méthode typées.models.ts– des interfaces TypeScript pour chaque schéma défini dans la spécification OpenAPI (par ex.,Article,User,Meta).
Comme le client est régénéré à partir de la spécification à chaque build CI, toute rupture dans Strapi apparaîtra comme une erreur de type avant que le code n’atteigne la production.
3. Configurer le client généré pour Next.js
3.1 Instance Axios centralisée
Créez un petit wrapper qui injecte le token JWT depuis les cookies. Cela fonctionne à la fois pour les composants serveur et client.
// src/lib/strapiClient.ts
import { Api } from '@/api';
import Cookies from 'js-cookie';
export const createStrapiClient = () => {
const baseURL = process.env.NEXT_PUBLIC_STRAPI_URL ?? 'http://localhost:1337';
const token = typeof window !== 'undefined' ? Cookies.get('token') : undefined;
return new Api({
baseURL,
headers: token ? { Authorization: `Bearer ${token}` } : undefined,
// optionnel : activer la journalisation des requêtes/réponses en dev
...(process.env.NODE_ENV === 'development' && {
requestInterceptor: (cfg) => {
console.log('Strapi request →', cfg.method?.toUpperCase(), cfg.url);
return cfg;
},
}),
});
};Le constructeur Api accepte n’importe quel objet de configuration Axios, vous pouvez donc ajouter des intercepteurs, un timeout ou des adaptateurs personnalisés selon vos besoins.
3.2 Helper côté serveur (getStaticProps / server actions)
Le code côté serveur peut lire le JWT directement depuis l’API cookies() de Next.js (disponible dans les composants serveur et les server actions).
// src/app/profile/page.tsx (composant serveur)
import { createStrapiClient } from '@/lib/strapiClient';
import { cookies } from 'next/headers';
export default async function ProfilePage() {
const token = cookies().get('token')?.value;
const client = createStrapiClient();
// Remplacer le token uniquement pour cette requête
client.instance.defaults.headers.Authorization = token ? `Bearer ${token}` : '';
const { data } = await client.v1.usersControllerGetProfileV1();
return (
<section>
<h1>Profil</h1>
<p>Nom : {data.username}</p>
<p>E‑mail : {data.email}</p>
</section>
);
}3.3 Récupération côté client avec SWR
Pour les pages interactives vous souhaitez généralement du cache et de la revalidation. SWR s’intègre parfaitement avec le client typé.
// src/components/ArticleList.tsx
'use client';
import useSWR from 'swr';
import { createStrapiClient } from '@/lib/strapiClient';
const client = createStrapiClient();
export default function ArticleList() {
const { data, error, isLoading } = useSWR(
'/articles',
() => client.v1.articlesControllerGetAllArticles().then((res) => res.data)
);
if (isLoading) return <p>Chargement…</p>;
if (error) return <p>Échec du chargement des articles.</p>;
return (
<ul>
{data?.map((article) => (
<li key={article.id}>{article.title}</li>
))}
</ul>
);
}Comme la fonction renvoie une Promise de la réponse typée, l’inférence générique de SWR conserve le type Article[], vous offrant une intellisense complète dans le composant.
4. Intégration du pipeline CI/CD
Ajoutez les étapes de génération de la spécification et de régénération du client à votre workflow CI afin que le front‑end corresponde toujours au back‑end.
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Install dependencies (frontend)
run: yarn install --cwd ./frontend
- name: Generate OpenAPI spec from Strapi
run: |
cd ./backend
yarn install
yarn strapi openapi generate --output ../frontend/docs/api-spec.json
- name: Regenerate TypeScript client
run: |
cd ./frontend
yarn generate:api
- name: Run type check & tests
run: |
cd ./frontend
yarn typecheck
yarn test
- name: Build Next.js app
run: |
cd ./frontend
yarn buildSi un changement dans Strapi ajoute, supprime ou renomme un endpoint, le client généré évoluera en conséquence. L’étape suivante yarn typecheck garantit que toute utilisation non conforme du code est détectée tôt.
5. Tester le client généré
Comme les signatures des méthodes du client sont dérivées du schéma OpenAPI, vous pouvez écrire des tests au niveau du type qui échouent à la compilation lorsque la spécification diverge.
// tests/api/articles.test.ts
import { createStrapiClient } from '@/lib/strapiClient';
test('fetch all articles returns Article[]', async () => {
const client = createStrapiClient();
const { data } = await client.v1.articlesControllerGetAllArticles();
// TypeScript garantira que data est de type Article[]
expect(Array.isArray(data)).toBe(true);
// Vérification de cohérence optionnelle à l’exécution
expect(data[0]).toHaveProperty('title');
});Si le back‑end modifie la forme de Article (par ex., ajoute un champ obligatoire publishedAt), le test continuera de compiler, mais votre code composant consommant Article devra être mis à jour ; le compilateur TypeScript vous le signalera.
6. Gérer le contenu versionné avec Revisionary (optionnel)
Si votre projet Strapi utilise le plugin Revisionary, la spécification OpenAPI inclut déjà les routes sensibles aux versions (/api/articles?publicationState=preview). Le client généré exposera celles‑ci comme des signatures de méthodes séparées, vous permettant de demander les brouillons, les versions publiées ou des révisions spécifiques sans code additionnel.
Pour plus d’informations sur l’extension du Content API par Revisionary, consultez le guide Content API dans la documentation de Strapi /docs/reference/content-api.
7. Déployer et vérifier
- Déployer le back‑end Strapi (veiller à ce que la spécification OpenAPI fasse partie des artefacts de build).
- Déployer l’application Next.js.
- Ouvrir une page qui utilise le client généré.
- Ouvrir la console du navigateur – vous devriez voir les journaux de requêtes si vous avez activé l’intercepteur dev.
- Inspecter l’onglet réseau – les réponses sont typées, et toute erreur 4xx/5xx apparaît comme une exception que vous pouvez attraper dans vos composants.
8. Pièges courants
| Symptôme | Cause probable | Solution |
|---|---|---|
api est undefined | Fichiers générés non compilés ou chemin incorrect | Vérifiez que import { Api } from '@/api'; correspond au dossier de sortie. |
| Erreurs de type après une mise à jour de Strapi | Spécification régénérée mais client non regénéré | Exécutez yarn generate:api localement ou ajoutez‑le au CI. |
| En‑têtes d’authentification manquants lors de la requête côté client | Bibliothèque de cookies non chargée ou nom du token différent | Assurez‑vous que js-cookie lit le même nom de cookie que vous avez défini après connexion. |
404 sur /api/openapi.json en production | Configuration du serveur bloque la route | Ajoutez la clé openapi à config/server.ts et activez l’accès public. |
9. Résumé
- Exporter la spécification OpenAPI avec
strapi openapi generate. - Générer un client Axios typé grâce à
swagger-typescript-api. - Envelopper le client dans un helper qui injecte le token JWT pour les contextes serveur et client.
- Consommer le client directement dans les composants serveur, les server actions ou les composants client basés sur SWR.
- Intégrer l’étape de génération dans votre pipeline CI/CD afin que les types front‑end restent synchronisés avec les évolutions de Strapi.
En suivant ces étapes, vous obtenez un pont maintenable et type‑safe entre Strapi 5 et une base de code Next.js moderne, éliminant le codage manuel des requêtes et réduisant les bugs d’exécution.
Sources
L’équipe Revisionary
Les développeurs de Revisionary, un plugin d’historique des versions pour Strapi 5. Nous écrivons sur Strapi, le développement web, l’IA et la sécurité des applications.
Cet article a été rédigé avec l'aide d'une IA.