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
04/09/2025, by Ivan

JSON:API ha molti concetti nella specifica, non tutti documentati qui. Tuttavia, gli utenti del modulo non hanno bisogno di comprendere completamente tutti i concetti della specifica per diventare produttivi con questo modulo. Se invece vuoi approfondire come sono strutturati i documenti di JSON:API, perché il modulo fa qualcosa in un modo piuttosto che in un altro, o semplicemente vuoi saperne di più sul design del modulo, si consiglia ai lettori di consultare la specifica su jsonapi.org.

Struttura del documento

JSON:API ha opinioni molto precise su come i documenti JSON devono essere strutturati e quali informazioni devono comparire in ogni corpo di richiesta e/o risposta.

Ogni corpo di richiesta/risposta deve essere racchiuso in un singolo oggetto JSON.

{
   // i tuoi dati qui...
}

I dati, o le informazioni specifiche di una risorsa o di più risorse, devono vivere all’interno di questo oggetto di primo livello sotto il “member” data. Un “member” è semplicemente una chiave predefinita nell’oggetto JSON. Il member data può essere un oggetto ({}) oppure un array ([]). Quando si crea o si aggiorna una risorsa, sarà sempre un singolo oggetto ({}) che rappresenta un singolo elemento. Solo quando si recupera una “collection” di più risorse questa proprietà sarà un array.

{
  "data": {
    // I dati della tua risorsa vanno qui.
  }
}

Altri member di primo livello includono: errors, meta, links e included. Tra questi, included sarà quello usato più spesso, ma verrà trattato più avanti nella documentazione.

Per ulteriori informazioni sulla struttura di primo livello, puoi consultare la specifica.

All’interno dei member data e included si trovano “resource objects” o “resource identifier objects”. I “resource objects” rappresentano il contenuto delle risorse (entità) con cui avrai a che fare. I “resource identifier objects” sono come chiavi esterne in un database: identificano una risorsa senza contenere nessuno dei campi di quella risorsa. In termini Drupal, un resource object è generalmente la rappresentazione JSON di una singola entità, che può essere un nodo, un termine di tassonomia o un utente. Sempre in termini Drupal, un resource identifier è solo l’informazione sufficiente a caricare un’entità: hai il suo tipo e il suo ID e nient’altro.

Ogni resource object deve contenere due member: type e id. L’unica eccezione è nella creazione di una nuova entità: in questo caso, l’id può essere omesso per permettere a Drupal di generare un id per la nuova risorsa. Tuttavia, è del tutto possibile che l’applicazione client fornisca un UUID per la risorsa durante la creazione di una nuova entità. Tutti gli ID in JSON:API sono UUID.

Il member type è sempre richiesto. Il valore per il member type deriva dal nome dell’entity type e dal bundle, quando applicabile. Il tipo per una risorsa segue sempre il pattern entity_type--bundle. Ad esempio, i tipi di nodo core article e basic page saranno rappresentati come: node--article e node--page.

Quindi, su un’entità senza proprietà o campi obbligatori, si può creare una nuova entità con il seguente JSON:

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

Questo però non sarebbe molto utile. Dobbiamo includere valori effettivi per l’entità. Per farlo, JSON:API ha due member per contenere valori: attributes e relationships. attributes memorizza valori specifici della risorsa sottostante. relationships sono valori che appartengono a un’altra risorsa nel sistema. In termini Drupal, relationships rappresentano solitamente valori memorizzati da un entity reference. Sul bundle core article di Drupal, questo potrebbe essere la proprietà uid, poiché uid è un entity reference all’utente che ha scritto l’articolo. Il corpo di un documento con attributes e relationships potrebbe apparire così:

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

Come puoi vedere, la proprietà uid si trova sotto il member relationships. Come la risorsa principale, contiene anch’essa un member type e un member id poiché è una risorsa distinta e separata.

Nota che uid non ha alcun attributes o relationships. Questo perché JSON:API non includerà il contenuto di una relazione a meno che non venga esplicitamente richiesto tramite un parametro di query speciale, include. Maggiori dettagli in seguito nella documentazione (vedi “Recuperare risorse (GET)”).

Per ulteriori dettagli sulla struttura dei resource objects, puoi consultare la specifica.

§ Identificatori di risorsa “virtuali”

In alcune circostanze, Drupal consente a una relazione di puntare a una risorsa (un entity reference che punta a un’entità) che non è memorizzata nel database e che quindi non è recuperabile tramite JSON:API. L’identificatore di risorsa “virtuale” può indicare situazioni diverse a seconda del contesto, ma corrisponderà sempre a una risorsa che non può essere trovata.

Uso e significato dell’identificatore di risorsa “virtuale” in Drupal core

Il campo parent dei termini di tassonomia è l’esempio più rilevante di questo caso particolare in Drupal core. Questo campo di relazione può contenere un resource identifier per una risorsa di termine di tassonomia “virtuale”. In questo caso, l’identificatore “virtuale” identifica il termine di tassonomia <root>. Ciò segnala che il termine di riferimento è al livello più alto del suo vocabolario.

Ecco un esempio di documento di risposta per un ipotetico termine di tassonomia:

{
  "data": {
    "type": "taxonomy_term--tags",
    "id": "2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e",
    "attributes": {
      "name": "Politica"
    },
    "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": "Uso e significato dell’identificatore di risorsa 'virtuale'."
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}

Nota come la relazione parent di questo Term (un campo di entity reference) ha un oggetto identificatore di risorsa in cui l’id non è un UUID, ma è "virtual". Questo è necessario perché un Term di livello radice ha un riferimento a un termine <root> non memorizzato (target_id = 0) come suo genitore.

Perché?

Dato che il termine root non è memorizzato e che un Term può avere più di un genitore, la domanda cruciale è: come distinguiamo tra un Term che:

  • ha solo il Term 3 come genitore ([3])?
  • ha sia questo termine root non memorizzato come genitore e un Term 3 ([0, 3])?

La risposta è che se JSON:API omettesse il termine root non memorizzato 0 invece di usare l’ID "virtual", non sarebbe possibile distinguere tra questi due casi!

§ Identificatori di risorsa “mancanti”

Drupal non “ripulisce” le relazioni verso risorse eliminate (campi di entity reference che puntano a entità eliminate). In altre parole: Drupal lascia inalterate le relazioni “penzolanti” (entity reference).

Quando JSON:API incontra tali relazioni penzolanti, utilizzerà l’identificatore di risorsa “missing”.

Uso e significato dell’identificatore di risorsa “missing” in Drupal core

Restando sull’esempio dato per l’identificatore “virtuale”: il campo parent dei termini di tassonomia. Immagina che un determinato termine di tassonomia avesse il termine “Belgio” come genitore, ma ora la risorsa di termine “Belgio” non esiste più — forse perché il piccolo paese del Belgio ha cessato di esistere. In questo caso, il campo di relazione conterrebbe un resource identifier per una risorsa di termine di tassonomia “missing”.

Ecco un esempio di documento di risposta per un ipotetico termine di tassonomia:

{
  "data": {
    "type": "taxonomy_term--tags",
    "id": "2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e",
    "attributes": {
      "name": "Politica"
    },
    "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": "Uso e significato dell’identificatore di risorsa 'missing'."
                  }
                }
              }
            }
          }
        ]
      }
    }
  }
}

Nota come la relazione parent di questo Term (un campo di entity reference) ha un oggetto identificatore di risorsa in cui l’id non è un UUID, ma è "missing". Non solo, ma il suo type è unknown (perché Drupal non memorizza il bundle dell’entità referenziata, ma solo il tipo di entità, quindi determinare il nome del resource type JSON:API è impossibile).

Articolo tratto dalla Documentazione di Drupal.