AEM GraphQL-API zur Verwendung mit Inhaltsfragmenten

Erfahren Sie, wie Sie Inhaltsfragmente in Adobe Experience Manager (AEM) mit der AEM GraphQL-API für die Headless-Bereitstellung von Inhalten verwenden.

AEM GraphQL-API, die mit Inhaltsfragmenten verwendet wird, basiert in hohem Maße auf der standardmäßigen Open-Source-GraphQL-API.

Die Verwendung der GraphQL-API in AEM ermöglicht die effiziente Bereitstellung von Inhaltsfragmenten an JavaScript-Clients in Headless CMS-Implementierungen:

  • Vermeiden von iterativen API-Anfragen wie bei REST,
  • Sicherstellen, dass die Bereitstellung auf die spezifischen Anforderungen beschränkt ist,
  • Ermöglichen der Massenbereitstellung von genau dem, was zum Rendern als Antwort auf eine einzelne API-Anfrage benötigt wird.
HINWEIS

GraphQL wird in zwei (separaten) Szenarien in Adobe Experience Manager (AEM) verwendet:

Voraussetzungen

Kunden, die GraphQL verwenden, sollten das AEM Inhaltsfragment mit GraphQL Index Package 1.0.5 installieren. Siehe Versionshinweise für weitere Informationen.

Die GraphQL-API

GraphQL ist:

  • …eine Abfragesprache für APIs und eine Laufzeitumgebung zur Erfüllung dieser Abfragen mit Ihren vorhandenen Daten. GraphQL bietet eine vollständige und verständliche Beschreibung der Daten in Ihrer API. Dadurch erhalten Kunden die Möglichkeit, genau nach dem zu fragen, was sie benötigen, und nichts mehr, was die Entwicklung von APIs im Laufe der Zeit erleichtert und leistungsstarke Entwickler-Tools ermöglicht.".

    Weitere Informationen finden Sie unter GraphQL.org

  • …eine offene Spezifikation für eine flexible API-Schicht. Überlagern Sie Ihre bestehenden Backends mit GraphQL, damit Sie Produkte schneller als je zuvor erstellen können…".

    Weitere Informationen finden Sie unter GraphQL entdecken.

  • "…eine Datenabfragesprache und -spezifikation, die von Facebook 2012 intern entwickelt wurden, bevor sie 2015 öffentlich zugänglich waren. Sie bietet eine Alternative zu REST-basierten Architekturen mit dem Ziel, die Produktivität von Entwicklern zu erhöhen und die Menge der übertragenen Daten zu minimieren. GraphQL wird von Hunderten von Unternehmen aller Größenordnungen in der Produktion eingesetzt …“

    Siehe GraphQL Foundation.

Weitere Informationen zur GraphQL-API finden Sie in den folgenden Abschnitten (unter vielen anderen Ressourcen):

Die GraphQL für AEM Implementierung basiert auf der standardmäßigen GraphQL Java™ Library. Siehe:

GraphQL-Terminologie

GraphQL verwendet Folgendes:

  • Abfragen

  • Schemata und Typen:

    • Schemata werden von AEM basierend auf den Inhaltsfragmentmodellen generiert.
    • GraphQL stellt mithilfe Ihrer Schemata die Typen und Vorgänge dar, die für die GraphQL-Implementierung für AEM zulässig sind.
  • Felder

  • GraphQL-Endpunkt

    • Der Pfad in AEM, der auf GraphQL-Abfragen antwortet und Zugriff auf die GraphQL-Schemata bietet.

    • Weitere Informationen finden Sie unter Aktivieren des GraphQL-Endpunkts.

In der (GraphQL.org) Einführung in GraphQL finden Sie ausführliche Informationen, einschließlich der Best Practices.

GraphQL-Abfragetypen

Mit GraphQL können Sie Abfragen für Folgendes durchführen:

AEM bietet Funktionen zum Konvertieren von Abfragen (beide Typen) in Beständige Abfragen die vom Dispatcher und dem CDN zwischengespeichert werden.

Best Practices für GraphQL-Abfragen (Dispatcher und CDN)

Die persistenten Abfragen sind die empfohlene Methode für die Nutzung bei Veröffentlichungsinstanzen, da:

  • sie zwischengespeichert werden
  • sie zentral von AEM verwaltet werden
HINWEIS

In der Regel gibt es keinen Dispatcher/CDN auf der Autoreninstanz, sodass die Verwendung persistenter Abfragen dort keinen Leistungsgewinn bringt. außer sie zu testen.

GraphQL-Abfragen über POST werden nicht empfohlen, da sie nicht zwischengespeichert werden. Daher ist der Dispatcher auf einer Standardinstanz so konfiguriert, dass er solche Abfragen blockiert.

GraphQL unterstützt zwar auch GET-Anfragen, diese Anfragen können jedoch Einschränkungen (z. B. die Länge der URL) erreichen, die durch die Verwendung persistenter Abfragen vermieden werden können.

HINWEIS

Die Möglichkeit, direkte Abfragen durchzuführen, könnte irgendwann in der Zukunft entfernt werden.

GraphiQL-Schnittstelle

Eine Implementierung der GraphiQL-Standardschnittstelle steht zur Verwendung mit AEM-GraphQL zur Verfügung.

HINWEIS

GraphiQL ist in allen Umgebungen von AEM enthalten (ist jedoch nur verfügbar/sichtbar, wenn Sie Ihre Endpunkte konfigurieren).

In früheren Versionen brauchten Sie ein Paket, um die GraphiQL IDE zu installieren. Wenn Sie dieses Paket installiert haben, kann es jetzt entfernt werden.

Über diese Schnittstelle können Sie Abfragen direkt eingeben und testen.

Beispiel:

  • http://localhost:4502/content/graphiql.html

Dies bietet Funktionen wie Syntaxhervorhebung, automatische Vervollständigung, automatische Vorschläge sowie einen Verlauf und eine Online-Dokumentation:

GraphiQL-Oberfläche

Anwendungsfälle für Autoren- und Veröffentlichungsumgebungen

Die Anwendungsfälle können vom Typ der AEM-Umgebung abhängen:

  • Veröffentlichungsumgebung; wird verwendet, um:

    • Daten für das JS-Programm (Standardanwendungsfall) abzufragen
  • Autorenumgebung; wird verwendet, um:

    • Daten für „Content-Management-Zwecke“ abzufragen:
      • GraphQL in AEM ist eine schreibgeschützte API.
      • Die REST-API kann für CR(u)D-Vorgänge verwendet werden.

Berechtigungen

Die Berechtigungen sind für den Zugriff auf Assets erforderlich.

GraphQL-Abfragen werden mit der Berechtigung des AEM-Benutzers der zugrunde liegenden Anfrage ausgeführt. Wenn der Benutzer keinen Lesezugriff auf einige (als Assets gespeicherte) Fragmente hat, wird er nicht Teil der Ergebnismenge.

Außerdem muss der Benutzer Zugriff auf einen GraphQL-Endpunkt haben, um GraphQL-Abfragen ausführen zu können.

Schema-Generierung

GraphQL ist eine typisierte API, d. h. die Daten müssen klar strukturiert und nach Typ geordnet sein.

Die GraphQL-Spezifikation enthält eine Reihe von Richtlinien zum Erstellen einer robusten API zum Abfragen von Daten in einer bestimmten Instanz. Um diese Richtlinien abzuschließen, muss ein Client die Schema, der alle für eine Abfrage erforderlichen Typen enthält.

Bei Inhaltsfragmenten basieren die GraphQL-Schemata (Struktur und Typen) auf aktivierten Inhaltsfragmentmodellen und deren Datentypen.

VORSICHT

Alle GraphQL-Schemata (abgeleitet von Inhaltsfragmentmodellen, die aktiviert wurden) können über den GraphQL-Endpunkt gelesen werden.

Diese Fähigkeit bedeutet, dass Sie sicherstellen müssen, dass keine sensiblen Daten verfügbar sind, da sie auf diese Weise durchsickert werden könnten. Beispielsweise enthält es Informationen, die in der Modelldefinition als Feldnamen enthalten sein könnten.

Wenn Benutzende beispielsweise ein Inhaltsfragmentmodell mit dem Namen Article erstellen, generiert AEM den GraphQL-Typ ArticleModel. Die Felder dieses Typs entsprechen den im Modell definierten Feldern und Datentypen. Außerdem werden einige Einstiegspunkte für Abfragen erstellt, die für diesen Typ gelten, z. B. articleByPath oder articleList.

  1. Ein Inhaltsfragmentmodell:

    Inhaltsfragmentmodell zur Verwendung mit GraphQL
  2. Das entsprechende GraphQL-Schema (Ausgabe aus der automatischen GraphiQL-Dokumentation):
    GraphQL-Schema basierend auf Inhaltsfragmentmodell

    Dieses Bild zeigt, dass der generierte Typ ArticleModel enthält mehrere fields.

    • Drei davon wurden vom Benutzer kontrolliert: author, mainund referencearticle.

    • Die anderen Felder wurden von AEM automatisch hinzugefügt und stellen hilfreiche Methoden zur Bereitstellung von Informationen zu einem bestimmten Inhaltsfragment dar. In diesem Beispiel (die Variable Helper-Felder) _path, _metadata, _variations.

  3. Nachdem ein Benutzer ein Inhaltsfragment basierend auf dem Modell „Article“ erstellt hat, kann es über GraphQL abgefragt werden. Beispiele finden Sie in den Beispielabfragen (basierend auf einer Beispielstruktur für Inhaltsfragmente zur Verwendung mit GraphQL).

In GraphQL für AEM ist das Schema flexibel. Diese Flexibilität bedeutet, dass sie bei jeder Erstellung, Aktualisierung oder Löschung eines Inhaltsfragmentmodells automatisch generiert wird. Die Datenschema-Caches werden auch aktualisiert, wenn Sie ein Inhaltsfragmentmodell aktualisieren.

Der Sites GraphQL-Service überwacht (im Hintergrund) alle Änderungen, die an einem Inhaltsfragmentmodell vorgenommen werden. Wenn Aktualisierungen erkannt werden, wird nur dieser Teil des Schemas neu generiert. Diese Optimierung spart Zeit und sorgt für Stabilität.

Wenn Sie zum Beispiel:

  1. ein Paket installieren, das Content-Fragment-Model-1 und Content-Fragment-Model-2 enthält:

    1. GraphQL-Typen für Model-1 und Model-2 generiert werden.
  2. anschließend Content-Fragment-Model-2 ändern:

    1. Nur die Model-2 Der GraphQL-Typ wird aktualisiert.

    2. in Erwägung nachstehender Gründe Model-1 bleibt gleich.

HINWEIS

Diese Details sollten Sie nur beachten, wenn Sie Massenaktualisierungen zu Inhaltsfragmentmodellen über die REST-API durchführen möchten oder anderweitig.

Das Schema wird über denselben Endpunkt wie die GraphQL-Abfragen bereitgestellt, wobei der Client die Tatsache behandelt, dass das Schema mit der GQLschema-Erweiterung aufgerufen wird. Beispielsweise können Sie eine einfache GET Anfrage an /content/cq:graphql/global/endpoint.GQLschema resultiert in der Ausgabe des Schemas mit dem Inhaltstyp: text/x-graphql-schema;charset=iso-8859-1.

Schemagenerierung – Nicht veröffentlichte Modelle

Wenn Inhaltsfragmente verschachtelt sind, kann es vorkommen, dass ein übergeordnetes Inhaltsfragmentmodell veröffentlicht wird, ein referenziertes Modell jedoch nicht.

HINWEIS

Die AEM-Benutzeroberfläche verhindert dies, aber wenn die Veröffentlichung programmgesteuert oder mit Inhaltspaketen erfolgt, kann es dazu kommen.

In diesem Fall generiert AEM eine unvollständig Schema für das übergeordnete Inhaltsfragmentmodell. Das bedeutet, dass die Fragmentreferenz, die vom nicht veröffentlichten Modell abhängt, aus dem Schema entfernt wird.

Felder

Innerhalb des Schemas gibt es einzelne Felder mit zwei grundlegenden Kategorien:

  • Von Ihnen generierte Felder.

    Eine Auswahl von Datentypen wird verwendet, um Felder basierend auf der Konfiguration Ihres Inhaltsfragmentmodells zu erstellen. Die Feldnamen werden aus dem Feld Eigenschaftsname des Datentyps entnommen.

    • Es gibt auch die Rendern als zu berücksichtigen, da Benutzer bestimmte Datentypen konfigurieren können. Beispielsweise kann ein einzeiliges Textfeld so konfiguriert werden, dass es mehrere einzeilige Texte enthält, indem Sie multifield aus dem Dropdown-Menü aus.
  • GraphQL für AEM generiert auch mehrere Helper-Felder.

    Diese Felder werden verwendet, um ein Inhaltsfragment zu identifizieren oder um weitere Informationen zu einem Inhaltsfragment zu erhalten.

Datentypen

GraphQL für AEM unterstützt eine Liste von Typen. Alle unterstützten Datentypen für Inhaltsfragmentmodelle und die entsprechenden GraphQL-Typen werden dargestellt:

Datentyp für Inhaltsfragmentmodelle GraphQL-Typ Beschreibung
Einzelzeilentext String, [String] Wird für einfache Zeichenfolgen wie Autorennamen und Ortsnamen verwendet.
Mehrzeiliger Text String Wird für die Ausgabe von Text verwendet, z. B. für den Textkörper eines Artikels
Zahl Float, [Float] Wird für die Anzeige von Gleitkommazahlen und regulären Zahlen verwendet
Boolesch Boolean Wird für die Anzeige von Kontrollkästchen → einfachen Wahr/Falsch-Aussagen verwendet
Datum und Uhrzeit Calendar Wird verwendet, um Datum und Uhrzeit in einem ISO 8086-Format anzuzeigen. Je nach ausgewähltem Typ gibt es drei Varianten, die in AEM-GraphQL verwendet werden können: onlyDate, onlyTime, dateTime
Aufzählung String Wird verwendet, um eine Option aus einer Liste von Optionen anzuzeigen, die bei der Modellerstellung definiert wurde
Tags [String] Wird verwendet, um eine Liste von Zeichenfolgen anzuzeigen, die in AEM verwendete Tags darstellen
Inhaltsreferenz String Wird verwendet, um den Pfad zu einem anderen Asset in AEM anzuzeigen
Fragmentreferenz Ein Modelltyp

Einzelnes Feld: Model - Modelltyp, direkt referenziert

Multifield mit einem referenzierten Typ: [Model] - Array des Typs Model, die direkt aus dem Array referenziert wird

Multifield mit mehreren referenzierten Typen: [AllFragmentModels] - Array aller Modelltypen, referenziert aus Array mit Vereinigungstyp
Wird verwendet, um auf ein oder mehrere Inhaltsfragmente bestimmter Modelltypen zu verweisen, die beim Erstellen des Modells definiert wurden

Hilfsfelder

Zusätzlich zu den Datentypen für benutzergenerierte Felder generiert GraphQL for AEM auch mehrere Helper -Felder, um ein Inhaltsfragment zu identifizieren oder zusätzliche Informationen zu einem Inhaltsfragment bereitzustellen.

Diese Hilfsfelder sind durch ein vorangestelltes _ gekennzeichnet, um zu unterscheiden, was vom Benutzer bzw. von der Benutzerin definiert und was automatisch generiert wurde.

Pfad

Das Pfadfeld wird in AEM GraphQL als Kennung verwendet. Es stellt den Pfad des Inhaltsfragment-Assets im AEM Repository dar. Dieser Pfad wird als Kennung eines Inhaltsfragments gewählt, da er:

  • innerhalb von AEM eindeutig ist,
  • leicht abgerufen werden kann.

Der folgende Code zeigt die Pfade aller Inhaltsfragmente, die basierend auf dem Inhaltsfragmentmodell erstellt wurden Person.

{
  personList {
    items {
      _path
    }
  }
}

Um ein einzelnes Inhaltsfragment eines bestimmten Typs abzurufen, müssen Sie auch zuerst dessen Pfad festlegen. Beispiel:

{
  authorByPath(_path: "/content/dam/path/to/fragment/john-doe") {
    item {
      _path
      firstName
      name
    }
  }
}

Siehe Beispielabfrage – ein Einzelstadtfragment.

Metadaten

Mit GraphQL stellt AEM auch die Metadaten eines Inhaltsfragments zur Verfügung. Metadaten sind Informationen, die ein Inhaltsfragment beschreiben, z. B.:

  • Titel eines Inhaltsfragments
  • den Miniaturansichtspfad
  • Beschreibung eines Inhaltsfragments
  • und das Erstellungsdatum.

Da Metadaten über den Schema-Editor generiert werden und daher keine bestimmte Struktur haben, wurde der GraphQL-Typ TypedMetaData implementiert, um die Metadaten eines Inhaltsfragments anzuzeigen. Die TypedMetaData stellt die Informationen bereit, die nach den folgenden Skalartypen gruppiert sind:

Feld
stringMetadata:[StringMetadata]!
stringArrayMetadata:[StringArrayMetadata]!
intMetadata:[IntMetadata]!
intArrayMetadata:[IntArrayMetadata]!
floatMetadata:[FloatMetadata]!
floatArrayMetadata:[FloatArrayMetadata]!
booleanMetadata:[BooleanMetadata]!
booleanArrayMetadata:[booleanArrayMetadata]!
calendarMetadata:[CalendarMetadata]!
calendarArrayMetadata:[CalendarArrayMetadata]!

Jeder Skalartyp repräsentiert entweder ein einzelnes Name-Wert-Paar oder ein Array von Name-Wert-Paaren, wobei der Wert dieses Paares dem Typ entspricht, in dem er gruppiert wurde.

Wenn Sie beispielsweise den Titel eines Inhaltsfragments abrufen möchten, ist diese Eigenschaft eine String -Eigenschaft, sodass Sie alle Zeichenfolgenmetadaten abfragen:

Abfragen von Metadaten:

{
  personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
    item {
      _path
      _metadata {
        stringMetadata {
          name
          value
        }
      }
    }
  }
}

Sie können alle GraphQL-Typen für Metadaten anzeigen, wenn Sie das generierte GraphQL-Schema anzeigen. Alle Modelltypen haben dieselben TypedMetaData.

HINWEIS

Unterschied zwischen normalen und Array-Metadaten
Beachten Sie, dass sich StringMetadata und StringArrayMetadata beide auf das beziehen, was im Repository gespeichert ist, und nicht darauf, wie Sie sie abrufen.

Beispielsweise durch Aufruf der stringMetadata -Feld erhalten Sie ein Array aller im Repository gespeicherten Metadaten als String. Und wenn Sie stringArrayMetadata, erhalten Sie ein Array aller im Repository gespeicherten Metadaten als String[].

Weitere Informationen finden Sie unter Beispielabfrage für Metadaten – Liste der Metadaten für Auszeichnungen mit dem Titel „GB“.

Varianten

Das Feld _variations wurde implementiert, um die Abfrage der Varianten eines Inhaltsfragments zu vereinfachen. Beispiel:

{
  personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
    item {
      _variations
    }
  }
}
HINWEIS

Die _variations enthält kein master Änderung der ursprünglichen Daten (referenziert als Übergeordnet in der Benutzeroberfläche) nicht als explizite Variante betrachtet.

Weitere Informationen finden Sie unter Beispielabfrage – Alle Städte mit einer gegebenen Variante.

HINWEIS

Wenn die angegebene Variante für ein Inhaltsfragment nicht vorhanden ist, werden die Originaldaten (auch als Übergeordnete Variante bezeichnet) als (Fallback-)Standard zurückgegeben.

GraphQL-Variablen

Mit GraphQL können Variablen in die Abfrage eingefügt werden. Weitere Informationen finden Sie unter GraphQL-Dokumentation für Variablen.

Um beispielsweise alle Inhaltsfragmente vom Typ Article abzurufen, die eine bestimmte Variante aufweisen, können Sie die Variable variation in GraphiQL angeben.

GraphQL-Variablen
### query
query GetArticlesByVariation($variation: String!) {
    articleList(variation: $variation) {
        items {
            _path
            author
            _variations
        }
    }
}

### in query variables
{
    "variation": "uk"
}

GraphQL-Anweisungen

In GraphQL besteht die Möglichkeit, die Abfrage anhand von Variablen, so genannten GraphQL-Richtlinien, zu ändern.

Sie können beispielsweise das Feld adventurePrice basierend auf einer Variablen includePrice in eine Abfrage für alle AdventureModels einfügen.

GraphQL-Anweisungen
### query
query GetAdventureByType($includePrice: Boolean!) {
  adventureList {
    items {
      adventureTitle
      adventurePrice @include(if: $includePrice)
    }
  }
}

### in query variables
{
    "includePrice": true
}

Filtern

Sie können auch Filterung in Ihren GraphQL-Abfragen verwenden, um bestimmte Daten zurückzugeben.

Beim Filtern wird eine Syntax verwendet, die auf logischen Operatoren und Ausdrücken basiert.

Der kleinste Teil ist ein einzelner Ausdruck, der auf den Inhalt eines bestimmten Felds angewendet werden kann. Er vergleicht den Inhalt des Felds mit einem gegebenen konstanten Wert.

Beispielsweise würde der folgende Ausdruck den Inhalt des Felds mit dem Wert vergleichen some textund sind erfolgreich, wenn der Inhalt dem Wert entspricht. Andernfalls schlägt der Ausdruck fehl:

{
  value: "some text"
  _op: EQUALS
}

Die folgenden Operatoren können verwendet werden, um Felder mit einem bestimmten Wert zu vergleichen:

Operator Typen Der Ausdruck ist erfolgreich, wenn …
EQUALS String, ID, Boolean … entspricht der Wert dem Inhalt des Felds
EQUALS_NOT String, ID … der Wert nicht identisch mit dem Inhalt des Felds ist
CONTAINS String … enthält der Inhalt des Felds den Wert ({ value: "mas", _op: CONTAINS } matches Christmas, Xmas, master, …)
CONTAINS_NOT String … der Inhalt des Felds nicht den Wert enthält
STARTS_WITH ID … beginnt die ID mit einem bestimmten Wert ({ value: "/content/dam/", _op: STARTS_WITH matches /content/dam/path/to/fragment, aber nicht /namespace/content/dam/something
EQUAL Int, Float … entspricht der Wert dem Inhalt des Felds
UNEQUAL Int, Float … der Wert nicht identisch mit dem Inhalt des Felds ist
GREATER Int, Float … der Inhalt des Felds größer als der Wert ist
GREATER_EQUAL Int, Float … der Inhalt des Felds größer oder gleich dem Wert ist
LOWER Int, Float … der Inhalt des Felds kleiner als der Wert ist
LOWER_EQUAL Int, Float … der Inhalt des Felds kleiner oder gleich dem Wert ist
AT Calendar, Date, Time … ist der Inhalt des Felds mit dem Wert identisch (einschließlich Zeitzoneneinstellung)
NOT_AT Calendar, Date, Time … der Inhalt des Felds nicht identisch mit dem Wert ist
BEFORE Calendar, Date, Time … der durch den Wert angegebene Zeitpunkt vor dem durch den Feldinhalt angegebenen Zeitpunkt liegt
AT_OR_BEFORE Calendar, Date, Time … der durch den Wert angegebene Zeitpunkt vor oder am selben durch den Feldinhalt angegebenen Zeitpunkt liegt
AFTER Calendar, Date, Time … der durch den Wert angegebene Zeitpunkt nach dem durch den Feldinhalt angegebenen Zeitpunkt liegt
AT_OR_AFTER Calendar, Date, Time … der durch den Wert angegebene Zeitpunkt nach oder am selben durch den Feldinhalt angegebenen Zeitpunkt liegt

Bei einigen Typen können Sie auch zusätzliche Optionen angeben, die die Art und Weise ändern, in der ein Ausdruck ausgewertet wird:

Option Typen Beschreibung
_ignoreCase String Ignoriert die Groß-/Kleinschreibung einer Zeichenfolge, z. B. den Wert time matches TIME, time, tImE, …
_sensitiveness Float Ermöglicht eine bestimmte Spanne für float-Werte, die als identisch betrachtet werden (um technische Einschränkungen aufgrund der internen Darstellung von float-Werten zu umgehen; sollte vermieden werden, da diese Option negative Auswirkungen auf die Leistung haben kann

Ausdrücke können mithilfe eines logischen Operators (_logOp) zu einer Gruppe kombiniert werden:

  • OR - der Satz von Ausdrücken erfolgreich sein, wenn mindestens ein Ausdruck erfolgreich ist
  • AND - der Satz von Ausdrücken erfolgreich, wenn alle Ausdrücke erfolgreich sind (Standard)

Jedes Feld kann anhand einer eigenen Ausdrucksgruppe gefiltert werden. Die Ausdruckssätze aller im Filterargument erwähnten Felder werden schließlich durch einen eigenen logischen Operator kombiniert.

Eine Filterdefinition (als das filter-Argument an eine Abfrage übergeben) enthält:

  • Eine Unterdefinition für jedes Feld (auf das Feld kann über seinen Namen zugegriffen werden, z. B. gibt es eine lastName im Filter für lastName im Feld "Datentyp"(Feld)
  • Jede Unterdefinition enthält _expressions -Array, das den Ausdruckssatz bereitstellt, und die _logOp -Feld, das den logischen Operator definiert, mit dem die Ausdrücke kombiniert werden sollen
  • Jeder Ausdruck wird durch den Wert (value-Feld) und den Operator (_operator-Feld) definiert, mit dem der Inhalt eines Felds verglichen werden soll

Sie können weglassen _logOp , wenn Sie Elemente mit AND und _operator , wenn Sie nach Gleichheit suchen möchten, da es sich bei diesen Werten um Standardwerte handelt.

Das folgende Beispiel zeigt eine vollständige Abfrage, die alle Personen filtert, die über eine lastName von Provo verfügen oder sjö enthalten, ohne die Groß-/Kleinschreibung zu beachten:

{
  authorList(filter: {
    lastname: {
      _logOp: OR
      _expressions: [
        {
          value: "sjö",
          _operator: CONTAINS,
          _ignoreCase: true
        },
        {
          value: "Provo"
        }
      ]
    }
  }) {
    items {
      lastName
      firstName
    }
  }
}

Sie können zwar auch nach verschachtelten Feldern filtern, dies wird jedoch nicht empfohlen, da es zu Leistungsproblemen führen kann.

Weitere Beispiele finden Sie unter:

Sortieren

Mit dieser Funktion können Sie die Abfrageergebnisse entsprechend einem bestimmten Feld sortieren.

Die Sortierkriterien:

  • ist eine kommagetrennte Liste von Werten, die den Feldpfad darstellen
    • Das erste Listenfeld definiert die primäre Sortierreihenfolge
      • das zweite Feld wird verwendet, wenn zwei Werte des primären Sortierkriteriums gleich sind
      • wird das dritte Feld verwendet, wenn die ersten beiden Kriterien identisch sind usw.
    • gepunktete Notation, z. B. field1.subfield.subfield usw.
  • mit optionaler Sortierrichtung
    • ASC (aufsteigend) oder DESC (absteigend); standardmäßig wird ASC angewendet
    • die Richtung kann pro Feld angegeben werden; Diese Fähigkeit bedeutet, dass Sie ein Feld in aufsteigender Reihenfolge sortieren können, ein anderes in absteigender Reihenfolge (name, firstName DESC)

Beispiel:

query {
  authorList(sort: "lastName, firstName") {
    items {
      firstName
      lastName
    }
  }
}

Ein weiteres Beispiel:

{
  authorList(sort: "lastName DESC, firstName DESC") {
    items {
        lastName
        firstName
    }
  }
}

Sie können auch ein Feld innerhalb eines verschachtelten Fragments mithilfe des Formats nestedFragmentname.fieldname sortieren.

HINWEIS

Dieses Format kann sich negativ auf die Leistung auswirken.

Beispiel:

query {
  articleList(sort: "authorFragment.lastName")  {
    items {
      title
      authorFragment {
        firstName
        lastName
        birthDay
      }
      slug
    }
  }
}

Paging

Mit dieser Funktion können Sie Paging für Abfragetypen durchführen, was eine Liste zurückgibt. Es werden zwei Methoden bereitgestellt:

  • offset und limit in einer List-Abfrage
  • first und after in einer Paginated-Abfrage

Listenabfrage – Versatz und Limit

In einer ...List-Abfrage können Sie offset und limit verwenden, um eine bestimmte Teilmenge der Ergebnisse zurückzugeben:

  • offset: Gibt den ersten zurückzugebenden Datensatz an
  • limit: Gibt die maximale Anzahl an zurückzugebenden Datensätzen an

Beispiel für die Ausgabe der Ergebnisseite, die bis zu fünf Artikel enthält, beginnend mit dem fünften Artikel aus der vollständigen Ergebnisliste:

query {
   articleList(offset: 5, limit: 5) {
    items {
      authorFragment {
        lastName
        firstName
      }
    }
  }
}
HINWEIS
  • Für das Paging ist eine stabile Sortierreihenfolge erforderlich, damit es bei mehreren Abfragen, die verschiedene Seiten desselben Ergebnisses anfordern, korrekt funktioniert. Standardmäßig wird der Repository-Pfad jedes Elements des Ergebnissatzes verwendet, um sicherzustellen, dass die Reihenfolge immer gleich ist. Wenn eine andere Sortierreihenfolge verwendet wird und diese Sortierung nicht auf JCR-Abfrageebene durchgeführt werden kann, hat dies negative Auswirkungen auf die Leistung. Der Grund dafür ist, dass der gesamte Ergebnissatz in den Speicher geladen werden muss, bevor die Seiten bestimmt werden.

  • Je höher der Offset, desto länger dauert es, die Elemente aus der vollständigen JCR-Abfrage-Ergebnismenge zu überspringen. Eine alternative Lösung für große Ergebnissätze ist die Verwendung der paginierten Abfrage mit der first- und after-Methode.

Paginiete Abfrage – „first“ und „after“

Der Abfragetyp ...Paginated verwendet die meisten ...List-Abfragetypfunktionen (Filtern, Sortieren), verwendet jedoch anstelle von offset/limit-Argumenten die first/after-Argumente gemäß der Definition in der GraphQL-Cursor-Verbindungsspezifikation. Eine weniger formale Einführung finden Sie in der Einführung in GraphQL.

  • first: Die n ersten zurückzugebenden Elemente.
    Der Standardwert lautet 50.
    Der Maximalwert ist 100.
  • after: Der Cursor, der den Anfang der angeforderten Seite bestimmt. Das durch den Cursor dargestellte Element ist nicht in der Ergebnismenge enthalten. Der Cursor eines Elements wird durch die cursor des edges Struktur.

Ein Beispiel für die Ausgabe einer Ergebnisseite mit bis zu fünf Abenteuern, beginnend mit dem angegebenen Cursor-Element in der vollständigen Ergebnisliste:

query {
    adventurePaginated(first: 5, after: "ODg1MmMyMmEtZTAzMy00MTNjLThiMzMtZGQyMzY5ZTNjN2M1") {
        edges {
          cursor
          node {
            title
          }
        }
        pageInfo {
          endCursor
          hasNextPage
        }
    }
}
HINWEIS
  • Standardmäßig verwendet Paging die UUID des Repository-Knotens, der das Fragment für die Reihenfolge darstellt, um sicherzustellen, dass die Reihenfolge der Ergebnisse immer gleich ist. Wenn sort verwendet wird, wird die UUID implizit genutzt um eine eindeutige Sortierung sicherzustellen, auch für zwei Elemente mit identischen Sortierschlüsseln.

  • Aufgrund interner technischer Einschränkungen verschlechtert sich die Leistung bei der Anwendung von Sortierung und Filterung auf verschachtelte Felder. Verwenden Sie daher Filter-/Sortierfelder, die auf der Stammebene gespeichert sind. Diese Technik wird auch empfohlen, wenn Sie große paginierte Ergebnismengen abfragen möchten.

GraphQL für AEM – Zusammenfassung der Erweiterungen

Die grundlegende Funktionsweise von Abfragen mit GraphQL für AEM entspricht der Standard-GraphQL-Spezifikation. Für GraphQL-Abfragen mit AEM gibt es einige Erweiterungen:

CORS-Filter

HINWEIS

Eine ausführliche Übersicht über die CORS-Richtlinie zur Ressourcenfreigabe in AEM finden Sie unter Grundlegendes zur Cross-Origin Resource Sharing (CORS).

Um auf den GraphQL-Endpunkt zuzugreifen, konfigurieren Sie eine CORS-Richtlinie im Git-Repository des Kunden. Diese Konfiguration erfolgt durch Hinzufügen einer entsprechenden OSGi-CORS-Konfigurationsdatei für einen oder mehrere gewünschte Endpunkte.

Diese Konfiguration muss eine vertrauenswürdige Website-Herkunft alloworigin oder alloworiginregexp angeben, für die der Zugriff gewährt werden muss.

Um beispielsweise den Zugriff auf den GraphQL-Endpunkt und den Persistenzabfrage-Endpunkt für https://my.domain zu gewähren, können Sie Folgendes verwenden:

{
  "supportscredentials":true,
  "supportedmethods":[
    "GET",
    "HEAD",
    "POST"
  ],
  "exposedheaders":[
    ""
  ],
  "alloworigin":[
    "https://my.domain"
  ],
  "maxage:Integer":1800,
  "alloworiginregexp":[
    ""
  ],
  "supportedheaders":[
    "Origin",
    "Accept",
    "X-Requested-With",
    "Content-Type",
    "Access-Control-Request-Method",
    "Access-Control-Request-Headers"
  ],
  "allowedpaths":[
    "/content/_cq_graphql/global/endpoint.json",
    "/graphql/execute.json/.*"
  ]
}

Wenn Sie einen Vanity-Pfad für den Endpunkt konfiguriert haben, können Sie ihn auch in allowedpaths verwenden.

Referrer-Filter

Zusätzlich zur CORS-Konfiguration muss ein Referrer-Filter konfiguriert werden, um den Zugriff von Drittanbieter-Hosts zuzulassen.

Dieser Filter erfolgt durch Hinzufügen einer entsprechenden OSGi Referrer Filter-Konfigurationsdatei, die:

  • einen vertrauenswürdigen Website-Hostnamen angibt (entweder allow.hosts oder allow.hosts.regexp),
  • Zugriff auf diesen Hostnamen gewährt.

Um beispielsweise Zugriff auf Anfragen mit dem Referrer my.domain zu gewähren, können Sie:

{
    "allow.empty":false,
    "allow.hosts":[
      "my.domain"
    ],
    "allow.hosts.regexp":[
      ""
    ],
    "filter.methods":[
      "POST",
      "PUT",
      "DELETE",
      "COPY",
      "MOVE"
    ],
    "exclude.agents.regexp":[
      ""
    ]
}
VORSICHT

Der Kunde ist für Folgendes verantwortlich:

  • Nur Zugriff auf vertrauenswürdige Domains gewähren
  • sicherstellen, dass keine sensiblen Informationen offen gelegt werden
  • Verwenden Sie keinen Platzhalter [*] Syntax; Diese Funktion deaktiviert den authentifizierten Zugriff auf den GraphQL-Endpunkt und stellt ihn auch der ganzen Welt zur Verfügung.
VORSICHT

Alle GraphQL-Schemata (abgeleitet von Inhaltsfragmentmodellen, die aktiviert wurden) können über den GraphQL-Endpunkt gelesen werden.

Diese Funktion bedeutet, dass Sie sicherstellen müssen, dass keine sensiblen Daten verfügbar sind, da sie auf diese Weise weitergeleitet werden könnten. Beispielsweise enthält es Informationen, die in der Modelldefinition als Feldnamen enthalten sein könnten.

Authentifizierung

Siehe Authentifizierung für AEM-GraphQL-Remote-Abfragen in Inhaltsfragmenten.

Häufig gestellte Fragen

Es wurden folgende Fragen aufgeworfen:

  1. F: „Wie unterscheidet sich die GraphQL-API für AEM von der Query Builder-API?

    • A:
      Die AEM-GraphQL-API bietet vollständige Kontrolle über die JSON-Ausgabe und ist ein Industriestandard für die Abfrage von Inhalten.
      In Zukunft plant AEM, in die AEM GraphQL-API zu investieren.
      "

Tutorial – Erste Schritte mit AEM Headless und GraphQL

Suchen Sie nach einem praktischen Tutorial? Checkout Erste Schritte mit AEM Headless und GraphQL End-to-End-Tutorial, in dem erläutert wird, wie Inhalte mithilfe AEM GraphQL-APIs erstellt und bereitgestellt werden, die von einer externen App in einem Headless-CMS-Szenario genutzt werden.

Auf dieser Seite