logo

Extra Block Types (EBT) - New Layout Builder experience❗

Extra Block Types (EBT) - styled, customizable block types: Slideshows, Tabs, Cards, Accordions and many others. Built-in settings for background, DOM Box, javascript plugins. Experience the future of layout building today.

Demo EBT modules Download EBT modules

❗Extra Paragraph Types (EPT) - New Paragraphs experience

Extra Paragraph Types (EPT) - analogical paragraph based set of modules.

Demo EPT modules Download EPT modules

Scroll
21/06/2025, by Ivan

JSON:API comprend de nombreux concepts dans sa spécification, dont tous ne sont pas documentés ici. Cependant, les utilisateurs du module n’ont pas besoin de comprendre complètement tous les concepts de la spécification pour être productifs avec ce module. Si vous souhaitez approfondir la structure des documents JSON:API, comprendre pourquoi le module agit de telle ou telle manière, ou simplement en apprendre davantage sur sa conception, il est recommandé de lire la spécification sur jsonapi.org.

Structure du document

JSON:API est très précis quant à la façon dont les documents JSON doivent être structurés et quelles informations doivent être incluses dans chaque corps de requête et/ou réponse.

Chaque corps de requête/réponse doit contenir un seul objet JSON au niveau supérieur.

{
   // vos données ici...
}

Les données, ou les informations spécifiques à une ou plusieurs ressources, doivent se trouver à l’intérieur de cet objet de premier niveau sous le membre data. Un "membre" est simplement une clé prédéfinie dans l’objet JSON. Le membre data peut être soit un objet ({}) ou un tableau ([]). Lors de la création ou de la mise à jour d’une ressource, ce sera toujours un objet unique ({}) représentant un élément unique. Ce n’est que lors de la récupération d’une "collection" de ressources multiples que cette propriété sera un tableau.

{
  "data": {
    // Vos données de ressource ici.
  }
}

D’autres membres de premier niveau incluent : errors, meta, links, et included. Parmi ceux-ci, included sera le plus souvent utilisé, mais il sera abordé plus tard dans la documentation.

Pour plus d’informations sur la structure de premier niveau, vous pouvez consulter la spécification.

Dans les membres data et included se trouvent des "objets ressource" ou "objets identifiants de ressource". Les "objets ressource" représentent le contenu des ressources (entités) concernées. Les "objets identifiants de ressource" sont comme des clés étrangères en base de données ; ils identifient une ressource sans contenir ses champs. En termes Drupal, un objet ressource est généralement la représentation JSON d’une seule entité, qui peut être un nœud unique, un terme de taxonomie unique, ou un utilisateur unique. Un identifiant de ressource contient juste assez d’informations pour charger une entité — vous avez son type et son ID, rien de plus.

Chaque objet ressource doit contenir deux membres : type et id. La seule exception est lors de la création d’une nouvelle entité, auquel cas l’id peut être omis pour permettre à Drupal de générer un ID. Cependant, il est tout à fait possible que l’application cliente fournisse un UUID lors de la création d’une nouvelle entité. Tous les ID dans JSON:API sont des UUID.

Le membre type est toujours obligatoire. Sa valeur est dérivée du nom du type d’entité et du bundle, si applicable. Le type pour une ressource d’entité suit toujours le modèle entity_type--bundle. Par exemple, les types de nœud "article" et "page basique" du noyau seront représentés par node--article et node--page.

Ainsi, pour une entité sans propriétés ou champs requis, on peut créer une nouvelle entité avec ce JSON :

{
  "data": {
    "type": "node--my-bundle",
  }
}

Cela ne serait pas très utile cependant. Il faut inclure des valeurs réelles pour l’entité. Pour cela, JSON:API utilise deux membres pour contenir les valeurs, attributes et relationships. attributes stockent les valeurs spécifiques à la ressource sous-jacente. relationships sont des valeurs qui appartiennent à une autre ressource dans le système. En termes Drupal, relationships représentent généralement des valeurs stockées par une référence d’entité. Sur le bundle article du noyau Drupal, cela peut être la propriété uid, car elle est une référence d’entité vers l’utilisateur qui a écrit l’article. Le corps d’un document avec attributes et relationships pourrait ressembler à ceci :

{
  "data": {
    "type": "node--my-bundle",
    "id": "2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e",
    "attributes": {
      "title": "Un Exemple"
    },
    "relationships": {
      "uid": {
        "data": {
          "type": "user--user",
          "id": "53bb14cc-544a-4cf2-88e8-e9cdd0b6948f"
        }
      }
    }
  }
}

Comme vous le voyez, la propriété uid est sous le membre relationships. Comme la ressource principale, elle contient aussi un membre type et un membre id, car il s’agit d’une ressource distincte.

Notez que uid n’a pas de attributes ou de relationships. En effet, JSON:API n’inclura pas le contenu d’une relation sauf si cela est explicitement demandé via un paramètre de requête spécial, include. Plus d’informations à ce sujet plus loin dans la documentation (voir "Récupération des ressources (GET)").

Pour plus de détails sur la structure des objets ressource, vous pouvez consulter la spécification.

§ Identifiants de ressource "virtuels"

Dans certaines circonstances, Drupal permet qu’une relation cible une ressource (une référence d’entité vers une entité) qui n’est pas stockée en base de données et donc non récupérable via JSON:API. L’identifiant de ressource "virtuel" peut indiquer différentes situations selon son contexte, mais correspondra toujours à une ressource introuvable.

Usage et signification de l’identifiant de ressource 'virtuel' dans le noyau Drupal

Le champ parent du terme de taxonomie est l’exemple le plus notable de ce cas spécial dans Drupal core. Ce champ de relation peut contenir un identifiant de ressource pour un terme de taxonomie "virtuel". Dans ce cas, cet identifiant "virtuel" désigne le terme de taxonomie <root>. Cela signifie que le terme référencé est au plus haut niveau de son vocabulaire.

Voici un exemple de document de réponse pour un terme de taxonomie hypothétique :

{
  "data": {
    "type": "taxonomy_term--tags",
    "id": "2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e",
    "attributes": {
      "name": "Politique"
    },
    "relationships": {
      "parent": {
        "data": [
          {
            "id": "virtual",
            "type": "taxonomy_term--tags",
            "meta": {
              "links": {
                "help": {
                  "href": "https://www.drupal.org/docs/8/modules/json-api/core-concepts#virtual",
                  "meta": {
                    "about": "Usage et signification de l’identifiant de ressource 'virtuel'."
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}

Notez comment la relation parent de ce terme (un champ de référence d’entité) contient un objet identifiant de ressource dont l’id n’est pas un UUID, mais la chaîne "virtual". Ceci est nécessaire car un terme de niveau racine ou supérieur possède comme parent un terme <root> non stocké (avec target_id = 0).

Pourquoi ?

Étant donné que le terme racine n’est pas stocké et qu’un terme peut avoir plusieurs parents, la question cruciale est : comment distinguer un terme qui :

  • a pour seul parent le terme 3 ([3]) ?
  • a à la fois ce terme racine non stocké comme parent et le terme 3 ([0, 3]) ?

La réponse est que si JSON:API omettait le terme racine non stocké 0 au lieu d’utiliser l’ID "virtual", il serait impossible de différencier ces deux cas !

§ Identifiants de ressource "manquants"

Drupal ne "nettoie" pas les relations vers des ressources supprimées (champs de référence d’entité qui pointent vers des entités supprimées). Autrement dit, Drupal conserve des relations "orphelines" en place.

Quand JSON:API rencontre de telles relations orphelines, il utilise l’identifiant de ressource "missing" (manquant).

Usage et signification de l’identifiant de ressource 'missing' dans le noyau Drupal

En reprenant l’exemple donné pour l’identifiant "virtual" : le champ parent du terme de taxonomie. Imaginez qu’un terme de taxonomie avait pour parent le terme "Belgique", mais que ce dernier n’existe plus — peut-être parce que le pays a cessé d’exister. Alors ce champ contiendra un identifiant de ressource pour un terme de taxonomie "missing".

Voici un exemple de document de réponse pour un terme de taxonomie hypothétique :

{
  "data": {
    "type": "taxonomy_term--tags",
    "id": "2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e",
    "attributes": {
      "name": "Politique"
    },
    "relationships": {
      "parent": {
        "data": [
          {
            "id": "missing",
            "type": "unknown",
            "meta": {
              "links": {
                "help": {
                  "href": "https://www.drupal.org/docs/8/modules/json-api/core-concepts#missing",
                  "meta": {
                    "about": "Usage et signification de l’identifiant de ressource 'missing'."
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}

Notez que la relation parent de ce terme contient un objet identifiant dont l’id n’est pas un UUID mais la chaîne "missing". De plus, son type est unknown car Drupal ne stocke pas le bundle de l’entité référencée, seulement le type d’entité, ce qui rend impossible la détermination du nom du type de ressource JSON:API.

Article extrait de la documentation Drupal.