AccueilClients

Applications et sites

  • Application métiersIntranet, back-office...
  • Applications mobilesAndroid & iOS
  • Sites InternetSites marketings et vitrines
  • Expertises techniques

  • React
  • TypeScript
  • Next.js
  • Expo / React Native
  • Node.js
  • Directus
  • Open SourceBlogContactEstimer

    19 juillet 2023

    Directus : le CMS headless open source

    7 minutes de lecture

    Directus : le CMS headless open source

    Dans le cadre d'une mission pour l'Office national de diffusion artistique, nous avons eu l'occasion de travailler avec le CMS headless Directus. Nous avons été séduits par sa simplicité d'utilisation et sa flexibilité. Nous vous proposons un retour sur les différents points techniques que nous avons aimés.

    Open-source

    Directus est un CMS headless (tel que Strapi) permettant de développer rapidement des backends/admin pour vos applications. Il offre une interface d'administration moderne et personnalisable, ainsi qu'une API REST / GraphQL pour consommer vos données.

    L'un des points forts de Directus est d'être entièrement open-source. Directus propose une offre Cloud assez coûteuse (99$ par mois), mais aussi la possibilité d'héberger le CMS sans frais.

    C'est bien sûr cette dernière option que nous avons choisie pour l'Onda afin d'avoir la main sur l'infrastructure et les coûts. Pour héberger Directus, il vous faudra une infrastructure classique permettant de faire tourner un serveur web Node.js.

    Créer un projet

    Initialiser un nouveau projet Directus est très simple grâce au CLI.

    La commande init permet d'installer les dépendances, configurer votre base de données (infos stockées dans un fichier .env) et créer l'utilisateur admin :

    npm init
    npm add directus
    
    npx directus init
    
    ? Choose your database client (Use arrow keys)
    ❯ PostgreSQL / Redshift
      CockroachDB (Beta)
      MySQL / MariaDB / Aurora
      SQLite
      Microsoft SQL Server
    ? Choose your database client PostgreSQL / Redshift
    ? Database Host: 127.0.0.1
    ? Port: 5432
    ? Database Name: directus
    ? Database User:
    ? Database Password:
    ? Enable SSL: (y/N)
    
    Create your first admin user:
    
    ? Email xxx@xxxx.xx
    ? Password ****
    
    Start Directus by running:
      npx directus start
    

    Ceci fait, vous pouvez lancer Directus :

    npx directus start
    

    Workflow de développement

    Création du modèle de données

    À l'image d'un CMS headless, Directus permet de créer vos modèles de données très simplement via une interface :

    Création d'une collection

    Créons par exemple une collection articles avec différents champs :

    Création des champs

    Directus va alors créer une table articles dans votre base de données avec les champs que vous avez définis.

    Table articles

    Un des avantages de Directus est de bien séparer vos données métiers et les données de configuration liées à Directus (le fait que le champ content doit-être du type markdown par exemple). Ainsi tout ce qui est lié à Directus est stocké dans des tables préfixées par directus_.

    Versionning du schéma

    Lors du cycle de développement, il est important de versionner votre modèle de données afin que différents développeurs puissent récupérer les changements. Pour cela, Directus offre deux commandes pour exporter et importer des snapshots via un fichier yaml ou json :

    npx directus schema snapshot ./snapshot.yaml
    
    // snapshot.yaml
    version: 1
    directus: 12.0.3
    vendor: postgres
    collections:
      - collection: articles
        meta:
          accountability: all
          archive_app_filter: true
          archive_field: null
          archive_value: null
          collapse: open
          collection: articles
          color: null
          display_template: null
          group: null
          hidden: false
          icon: null
          item_duplication_fields: null
          note: null
          preview_url: null
          singleton: false
          sort: null
          sort_field: null
          translations: null
          unarchive_value: null
        schema:
          name: articles
    // ...
    

    Vous pouvez ainsi versionner ce schéma et récupérer les changements grâce à la commande apply :

    npx directus schema apply ./snapshot.yaml
    

    Cette commande doit aussi être lancée lors de vos déploiements (via un CI par exemple) afin de mettre à jour le schéma de votre base de données.

    OpenAPI et TypeScript

    Spécification OpenAPI

    Qui dit CMS headless, dit frontend pour consommer les données. Ce front peut-être par exemple une application Next.js qui va se connecter à l'API de Directus pour récupérer vos données. Il est alors fort utile d'avoir un contrat fort de typage entre l'api et le front. Nous pouvons utiliser la spécification OpenAPI générée par Directus et créer les types TypeScript associés.

    Directus expose la spécification à l'adresse suivante :

    http://0.0.0.0:8055/server/specs/oas?access_token=VOTRE_TOKEN

    openapi "3.0.1"
    info	{}
    servers	[]
    paths	{}
    tags []
    components {}
    

    Afin d'avoir accès à l'ensemble du schéma, il vous faudra générer un token statique depuis un utilisateur administrateur. On regrette le fait de ne pas pouvoir générer un token statique global sans passer par un utilisateur.

    Il est important de relever que la spécification OpenAPI générée prend en compte les permissions liés au token. Ainsi sans token, si le rôle Public a seulement accès en lecture aux endpoints de lecture des articles, uniquement ces derniers seront retournés dans la spécification :

    Rôles

    On découvre par la même occasion la gestion très fine des rôles et permissions de Directus. Pour chaque rôle défini, nous pouvons définir les permissions CRUD sur chaque collection (et même aller sur une granularité plus fine grâce à un système de règles).

    Typages avec TypeScript

    Nous avons déjà évoqué le workflow de génération de types TypeScript depuis une spécification OpenAPI dans un précédent article.

    Depuis votre front, vous pouvez utiliser la librairie swagger-typescript-api afin de générer les types associés à votre API :

    swagger-typescript-api -p http://0.0.0.0:8055/server/specs/oas?access_token=VOTRE_TOKEN -o src/generated -n types.d.ts
    

    Directus offre un SDK TypeScript pour facilement requêter votre API en utilisant vos types TS :

    import { ItemsArticles } from '@/generated/types'
    import { Directus } from '@directus/sdk'
    
    type Collections = {
      articles: ItemsArticles
    }
    
    const directus = new Directus<Collections>(process.env.NEXT_PUBLIC_API_HOST)
    const articles = await directus
      .items('articles')
      .readByQuery({ filter: { title: { _contains: 'Hello world' } } })
    

    Next.js et génération statique

    Le site de l'Onda est une application Next.js 13 qui vient consommer directement l'API exposée par Directus. Les pages sont générées statiquement lors du build puis sont regénérées automatiquement lorsque des changements sont détectés.

    Un tel workflow peut être mis en place facilement avec le mécanisme de revalidation de Next.js ainsi que les flux webhooks de Directus.

    Route d'API Next.js côté front pour regénérer une page :

    import { revalidatePath } from 'next/cache'
    import { NextRequest, NextResponse } from 'next/server'
    
    export async function GET(request: NextRequest) {
      if (!request.url) {
        return new Response('Invalid request', { status: 400 })
      }
    
      const { searchParams } = new URL(request.url)
    
      const secret = searchParams.get('secret')
      const path = searchParams.get('path')
    
      if (!secret || secret !== process.env.INVALIDATE_SECRET_TOKEN || !path) {
        return new Response('Invalid credentials or missing path', {
          status: 400,
        })
      }
    
      revalidatePath(path)
    
      return NextResponse.json({
        revalidated: true,
        now: Date.now(),
      })
    }
    

    Mise en place d'un flux d'invalidation côté Directus :

    Invalidation

    Un système d'extensions complet

    Directus offre également la possibilité d'étendre ses fonctionnalités grâce à un système d'extensions. Il est possible de créer plusieurs types d'extensions, parmi lesquels :

    Cela permet de facilement étendre Directus pour répondre à des besoins spécifiques. À noter que Directus est développé en Vue.js : toutes les interfaces doivent donc être développées avec cette librairie. En tant qu'agence spécialisée en React, nous aurions aimé un binding agnostique et pouvoir développer nos interfaces avec React.

    Nous avons aussi utilisé Prisma au sein des extensions de type serveur (endpoints, hooks, listeners…) afin de bénéficier d'un query builder TypeScript puissant. Grâce à la commande pull, nous pouvons récupérer le schéma et bénéficier du client Prisma :

    prisma db pull
    prisma generate
    

    Derniers mots

    Les points forts

    Pour finir voici les autres points qui nous ont séduits dans Directus :

    • Un écosystème vivace : des releases régulières, une communauté active et une documentation de qualité ;
    • Un système de permissions complet : pour un rôle donné, il est possible de définir des permissions avec une granularité très fine ;
    • Une UX/UI de qualité : Directus est très agréable à utiliser et offre une UX moderne avec le souci du détail ;
    • Un haut niveau de personnalisation : grâce à de nombreuses options, il est possible de personnaliser l'interface de Directus pour répondre à vos besoins sans trop de développements custom ;
    • Un système de workflows : grâce à un outil no-code intégré, vous pouvez facilement mettre en place des workflows sur vos données métiers ;
    • Une gestion des traductions : gérer plusieurs langues dans vos collections est très simple avec Directus ;

    Ce que nous aimons moins

    • Interfaces des extensions en Vue.js plutôt que React.js, mais c'est personnel 😁 ;
    • Des conflits GIT sur le fichier de snapshot du schéma parfois assez complexes à résoudre ;

    Beaucoup de points positifs donc pour Directus : un outil que nous ajoutons à notre stack technique avec grand plaisir ! Nous pensons donc à l'avenir partir sur Directus plutôt que Strapi. En effet, Directus offre une meilleure UX/UI/DX, un écosystème plus mature et permet de mieux s'adapter aux règles métiers de nos clients.

    À découvrir également

    Premier Octet vous accompagne dans le développement de vos projets avec directus

    En savoir plusNous contacter
    18 avenue Parmentier
    75011 Paris
    +33 1 43 57 39 11
    hello@premieroctet.com

    Suivez nos aventures

    GitHub

    X

    Flux RSS

    Bluesky

    Naviguez à vue