Zentrale Konzepte
JSON:API hat viele Konzepte in der Spezifikation, die hier nicht alle dokumentiert sind. Allerdings müssen Nutzer des Moduls nicht alle Konzepte der Spezifikation vollständig verstehen, um produktiv mit dem Modul zu arbeiten. Wenn Sie tiefer einsteigen möchten, wie JSON:API-Dokumente aufgebaut sind, warum das Modul etwas auf eine bestimmte Weise macht oder einfach mehr über das Design des Moduls erfahren möchten, sollten Sie die Spezifikation auf jsonapi.org lesen.
Dokumentenstruktur
JSON:API ist sehr strikt bezüglich der Struktur von JSON-Dokumenten und der Informationen, die in jeder Anfrage und/oder Antwort enthalten sein müssen.
Jeder Request/Response-Body muss unter einem einzigen JSON-Objekt liegen.
{
// Ihre Daten hier...
}
Die Daten, also die Informationen zu einer Ressource oder mehreren Ressourcen, müssen innerhalb dieses obersten Objekts unter dem data
-„Member“ leben. Ein „Member“ ist einfach ein vordefinierter Schlüssel im JSON-Objekt. Das data
-Member kann entweder ein Objekt ({}
) oder ein Array ([]
) sein. Beim Erstellen oder Aktualisieren einer Ressource ist dies immer ein einzelnes Objekt ({}
), das ein einzelnes Element darstellt. Nur beim Abrufen einer „Sammlung“ mehrerer Ressourcen ist diese Eigenschaft ein Array.
{
"data": {
// Ihre Ressourcendaten hier.
}
}
Weitere Top-Level-Member sind: errors
, meta
, links
und included
. Von diesen wird included
am häufigsten verwendet, aber später in der Dokumentation behandelt.
Weitere Informationen zur Top-Level-Struktur finden Sie in der Spezifikation.
Innerhalb der data
- und included
-Member befinden sich „Ressourcenobjekte“ oder „Ressourcen-Identifikator-Objekte“. „Ressourcenobjekte“ repräsentieren den Inhalt der Ressourcen (Entitäten), mit denen Sie arbeiten werden. „Ressourcen-Identifikator-Objekte“ sind wie Fremdschlüssel in einer Datenbank; sie identifizieren eine Ressource, ohne irgendwelche Felder dieser Ressource zu enthalten. In Drupal-Begriffen ist ein Ressourcenobjekt im Allgemeinen die JSON-Darstellung einer einzelnen Entität, etwa eines einzelnen Nodes, eines Taxonomiebegriffs oder eines einzelnen Benutzers. Wiederum in Drupal-Begriffen ist ein Ressourcen-Identifikator gerade genug Information, um eine Entität zu laden – Sie haben deren Typ und ID, aber nichts anderes.
Jedes Ressourcenobjekt muss zwei Member enthalten: type
und id
. Die einzige Ausnahme ist beim Erstellen einer neuen Entität – in diesem Fall kann das id
weggelassen werden, damit Drupal eine ID für die neue Ressource generiert. Es ist jedoch durchaus möglich, dass die Client-Anwendung beim Erstellen einer neuen Entität eine UUID für die Ressource bereitstellt. Alle IDs in JSON:API sind UUIDs.
Das type
-Member ist immer erforderlich. Der Wert für das Typ-Member leitet sich aus dem Namen des Entitätstyps und dem Bundle ab, falls vorhanden. Der Typ für eine Entitätsressource folgt immer dem Muster entity_type--bundle
. Beispielsweise werden die Core-Typen „article“ und „basic page“ als node--article
und node--page
dargestellt.
Daher kann man bei einer Entität ohne erforderliche Eigenschaften oder Felder eine neue Entität mit folgendem JSON erstellen:
{
"data": {
"type": "node--my-bundle",
}
}
Das wäre jedoch wenig nützlich. Wir müssen tatsächliche Werte für die Entität angeben. Dafür hat JSON:API zwei Member für Werte: attributes
und relationships
. attributes
speichern Werte, die spezifisch für die zugrundeliegende Ressource sind. relationships
sind Werte, die zu einer anderen Ressource im System gehören. In Drupal stellen relationships
in der Regel Werte dar, die durch eine Entitätsreferenz gespeichert werden. Im Core-Artikel-Bundle von Drupal könnte dies die uid
-Eigenschaft sein, da die uid
-Eigenschaft eine Entitätsreferenz auf den Benutzer ist, der den Artikel verfasst hat. Der Body eines Dokuments mit attributes
und relationships
könnte etwa so aussehen:
{
"data": {
"type": "node--my-bundle",
"id": "2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e",
"attributes": {
"title": "Ein Beispiel"
},
"relationships": {
"uid": {
"data": {
"type": "user--user",
"id": "53bb14cc-544a-4cf2-88e8-e9cdd0b6948f"
}
}
}
}
}
Wie Sie sehen, befindet sich die uid
-Eigenschaft unter dem relationships
-Member. Wie die Hauptressource enthält sie ebenfalls ein type
- und ein id
-Member, da es sich um eine eigene Ressource handelt.
Beachten Sie, dass uid
keine attributes
oder relationships
hat. Das liegt daran, dass JSON:API den Inhalt einer Beziehung nur dann einfügt, wenn dies ausdrücklich über einen speziellen Query-Parameter include
angefordert wird. Mehr dazu später in der Dokumentation (siehe "Ressourcen abrufen (GET)").
Weitere Details zur Struktur von Ressourcenobjekten finden Sie in der Spezifikation.
§ „Virtuelle“ Ressourcen-Identifikatoren
In manchen Fällen erlaubt es Drupal, dass eine Beziehung auf eine Ressource verweist (eine Entitätsreferenz auf eine Entität), die nicht in der Datenbank gespeichert ist und daher nicht über JSON:API abgerufen werden kann. Der „virtuelle“ Ressourcen-Identifikator kann je nach Kontext unterschiedliche Umstände signalisieren, entspricht jedoch immer einer Ressource, die nicht gefunden werden kann.
Verwendung und Bedeutung des „virtuellen“ Ressourcen-Identifikators im Drupal Core
Das Taxonomie-Term-Feld parent
ist das bemerkenswerteste Beispiel für diesen Spezialfall im Drupal-Core. Dieses Beziehungsfeld kann einen Ressourcen-Identifikator für eine „virtuelle“ Taxonomie-Term-Ressource enthalten. In diesem Fall identifiziert der „virtuelle“ Ressourcen-Identifikator den <root>
-Taxonomiebegriff. Dies signalisiert, dass der referenzierende Begriff auf der obersten Ebene seines Vokabulars steht.
Sehen Sie sich als Beispiel folgendes Antwortdokument für einen hypothetischen Taxonomiebegriff an:
{
"data": {
"type": "taxonomy_term--tags",
"id": "2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e",
"attributes": {
"name": "Politics"
},
"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": "Verwendung und Bedeutung des 'virtuellen' Ressourcen-Identifikators."
}
}
}
}
}
]
}
}
}
}
Beachten Sie, wie die parent
-Beziehung (ein Entitätsreferenzfeld) dieses Term
ein Ressourcen-Identifikator-Objekt hat, bei dem id
keine UUID ist, sondern "virtual"
. Dies ist notwendig, weil ein oberstes oder Wurzel-Term
eine Referenz auf ein nicht gespeichertes <root>
-Term (target_id = 0
) als Parent hat.
Warum?
Da das Root-Term nicht gespeichert ist und ein Term
mehr als einen Parent haben kann, ist die entscheidende Frage: Wie unterscheiden wir zwischen einem Term
, das:
- nur
Term
3
als Parent hat ([3]
)? - sowohl dieses nicht gespeicherte Root-
Term
als Parent undTerm
3
([0, 3]
)?
Die Antwort: Wenn JSON:API das nicht gespeicherte Root-Term 0
einfach weglassen würde, anstatt die "virtual"
-ID zu nutzen, wäre es nicht möglich, zwischen diesen beiden Fällen zu unterscheiden!
§ „Fehlende“ Ressourcen-Identifikatoren
Drupal „bereinigt“ Beziehungen zu gelöschten Ressourcen nicht (Entitätsreferenzfelder, die auf gelöschte Entitäten verweisen). Anders gesagt: Drupal lässt „hängende“ Beziehungen (Entity References) bestehen.
Wenn JSON:API auf solche hängenden Beziehungen stößt, wird der „missing“-Ressourcen-Identifikator verwendet.
Verwendung und Bedeutung des „missing“-Ressourcen-Identifikators im Drupal Core
Bleiben wir beim Beispiel des „virtuellen“ Ressourcen-Identifikators: das parent
-Feld eines Taxonomiebegriffs. Angenommen, ein bestimmter Taxonomiebegriff hatte früher den Taxonomiebegriff „Belgien“ als Parent, aber dieser Begriff existiert nun nicht mehr – vielleicht, weil das kleine Land Belgien nicht mehr existiert. Dann würde dieses Beziehungsfeld einen Ressourcen-Identifikator für eine „fehlende“ Taxonomie-Term-Ressource enthalten.
Sehen Sie sich als Beispiel folgendes Antwortdokument für einen hypothetischen Taxonomiebegriff an:
{
"data": {
"type": "taxonomy_term--tags",
"id": "2ee9f0ef-1b25-4bbe-a00f-8649c68b1f7e",
"attributes": {
"name": "Politics"
},
"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": "Verwendung und Bedeutung des 'missing'-Ressourcen-Identifikators."
}
}
}
}
}
]
}
}
}
}
Beachten Sie, wie die parent
-Beziehung (ein Entitätsreferenzfeld) dieses Term
ein Ressourcen-Identifikator-Objekt hat, bei dem id
keine UUID ist, sondern "missing"
. Außerdem ist dessen type
unknown
(da Drupal das Bundle der referenzierten Entität nicht speichert, sondern nur den Entitätstyp, kann der JSON:API-Resourcentypname nicht bestimmt werden).
Artikel aus der Drupal Dokumentation.