L’API GraphQL d’Adobe Experience Manager as a Cloud Service (AEM) utilisée avec des fragments de contenu repose principalement sur l’API open source standard GraphQL.
L’utilisation de l’API GraphQL dans AEM permet la diffusion efficace de fragments de contenu aux clients JavaScript dans les implémentations CMS découplées :
GraphQL est actuellement utilisé comme Cloud Service dans deux scénarios (distincts) à Adobe Experience Manager (AEM) :
GraphQL est :
« …un langage de requête pour les API et un environnement d’exécution pour répondre à ces requêtes avec vos données existantes. GraphQL fournit une description complète et compréhensible des données de votre API, permet aux clients de demander exactement ce dont ils ont besoin et rien de plus, facilite l’évolution des API au fil du temps et donne accès à de puissants outils de développement. ».
Voir GraphQL.org
« …une spécification ouverte pour une couche d’API flexible. Placez GraphQL sur vos back-ends existants pour créer des produits plus rapidement que jamais… ».
Voir Explore GraphQL.
"…un langage et une spécification de requête de données développé en interne par Facebook en 2012 avant d'être publiquement ouvert en 2015. C’est une alternative aux architectures basées sur REST destinée à accroître la productivité des développeurs et à réduire les quantités de données transférées. GraphQL est utilisé en production par des centaines d'organisations de toutes tailles…"
Voir GraphQL Foundation.
Pour plus d’informations sur l’API GraphQL, voir les sections suivantes (parmi de nombreuses autres ressources) :
Sur graphql.org :
Sur graphql.com :
La mise en œuvre GraphQL pour AEM repose sur la bibliothèque Java GraphQL standard. Voir :
GraphQL utilise les éléments suivants :
Chemin d’accès dans AEM qui répond aux requêtes GraphQL et permet d’accéder aux schémas GraphQL.
Voir Activation de votre point de terminaison GraphQL pour plus de détails.
Voir la Présentation de GraphQL (GraphQL.org) pour des détails complets, y compris les Bonnes pratiques.
Avec GraphQL, vous pouvez exécuter des requêtes pour renvoyer l'un ou l'autre des éléments suivants :
Une entrée unique
Le point d’entrée est le chemin utilisé pour accéder à GraphQL pour AEM. Avec ce chemin, vous (ou votre application) pouvez :
Le chemin d’accès au référentiel de GraphQL pour AEM point de terminaison est :
/content/cq:graphql/global/endpoint
Votre application peut utiliser le chemin d’accès suivant dans l’URL de demande :
/content/_cq_graphql/global/endpoint.json
Pour activer le point de terminaison pour GraphQL pour AEM, vous devez :
Ces mesures sont susceptibles de changer dans un avenir proche.
Voir Supporting Packages pour plus d'informations sur les packages fournis par Adobe pour simplifier ces étapes.
Pour activer les requêtes GraphQL dans AEM, créez un point de terminaison à /content/cq:graphql/global/endpoint
:
cq:graphql
et global
doivent être de type sling:Folder
.endpoint
doit être de type nt:unstructured
et contenir sling:resourceType
de graphql/sites/components/endpoint
.Le point de terminaison est accessible à tous. Ceci peut, en particulier sur les instances de publication, poser un problème de sécurité, car les requêtes GraphQL peuvent imposer une charge importante au serveur.
Vous pouvez configurer des listes de contrôle d’accès, en fonction de votre cas d’utilisation, sur le point de terminaison.
Votre point de terminaison ne fonctionnera pas de manière standard. Vous devrez fournir d'autres configurations pour le point de terminaison GraphQL séparément.
De plus, vous pouvez tester et déboguer des requêtes GraphQL à l'aide de l'IDE GraphiQL.
Voir Supporting Packages pour plus d'informations sur les packages fournis par Adobe pour simplifier ces étapes.
Des configurations supplémentaires sont requises :
org.apache.sling.graphql.core.GraphQLServlet
. Il doit être fourni en tant que configuration d’usine OSGi.sling.servlet.extensions
doit être définie sur [json]
sling.servlet.methods
doit être définie sur [GET,POST]
sling.servlet.resourceTypes
doit être définie sur [graphql/sites/components/endpoint]
com.adobe.aem.graphql.sites.adapters.SlingSchemaServlet
. Il doit être fourni en tant que configuration d’usine OSGi.sling.servlet.extensions
doit être définie sur [GQLschema]
sling.servlet.methods
doit être définie sur [GET]
sling.servlet.resourceTypes
doit être définie sur [graphql/sites/components/endpoint]
com.adobe.granite.csrf.impl.CSRFFilter
/content/cq:graphql/global/endpoint
à la liste existante des chemins exclus (filter.excluded.paths
)Pour simplifier la configuration d’un point de terminaison GraphQL, l’Adobe fournit le package Exemple de projet GraphQL.
Cette archive contient à la fois la configuration supplémentaire requise et le point de terminaison GraphQL. S'il est installé sur une instance AEM ordinaire, il expose un point de terminaison GraphQL entièrement fonctionnel à /content/cq:graphql/global/endpoint
.
Ce paquet est destiné à être un plan d'ensemble pour vos propres projets GraphQL. Consultez le package README pour plus d'informations sur l'utilisation du package.
Si vous préférez créer manuellement la configuration requise, Adobe fournit également un package de contenu GraphQL Endpoint Content dédié. Ce package de contenu contient uniquement le point de terminaison GraphQL, sans aucune configuration.
Une implémentation de l'interface standard GraphiQL est disponible pour une utilisation avec AEM GraphQL. Il peut être installé avec AEM.
Cette interface vous permet de saisir directement et de tester les requêtes.
Par exemple :
http://localhost:4502/content/graphiql.html
Vous disposez de fonctionnalités telles que la mise en surbrillance de la syntaxe, la saisie semi-automatique et la suggestion automatique, ainsi qu’un historique et une documentation en ligne :
L'interface utilisateur de GraphiQL peut être installée sur AEM avec un package dédié : le package GraphiQL Content Package v0.0.4.
Les cas d’utilisation peuvent dépendre du type d’environnement AEM as a Cloud Service :
Environnement de publication, utilisé pour :
Environnement de création, utilisé pour :
Les autorisations sont celles requises pour accéder aux ressources.
GraphQL est une API dans laquelle les données doivent être clairement structurées et organisées par type.
La spécification GraphQL fournit une série de directives sur la création d’une API robuste pour interroger les données sur une certaine instance. Un client doit pour cela récupérer le Schéma, qui contient tous les types nécessaires pour une requête.
Pour les fragments de contenu, les schémas GraphQL (structure et types) sont basés sur Activé Modèles de fragments de contenu et leurs types de données.
Tous les schémas GraphQL (dérivés de modèles de fragments de contenu qui ont été activés) sont lisibles par le point de terminaison GraphQL.
Cela signifie que vous devez vous assurer qu’aucune donnée sensible n’est disponible, car elle peut être divulguée de cette façon ; par exemple, cela inclut des informations qui peuvent être présentes sous forme de noms de champ dans la définition de modèle.
Par exemple, si un utilisateur a créé un modèle de fragment de contenu nommé Article
, AEM génère l’objet article
de type ArticleModel
. Les champs de ce type correspondent aux champs et aux types de données définis dans le modèle.
Un modèle de fragment de contenu :
Schéma GraphQL correspondant (sortie de la documentation automatique GraphiQL) :
Cela montre que le type généré ArticleModel
contient plusieurs champs.
Trois d’entre eux ont été contrôlés par l’utilisateur : author
, main
et referencearticle
.
Les autres champs ont été ajoutés automatiquement par AEM et représentent des méthodes utiles pour fournir des informations sur un certain fragment de contenu ; dans cet exemple, _path
, _metadata
et _variations
. Ces champs d'assistance sont marqués par un _
précédent pour distinguer ce qui a été défini par l'utilisateur de ce qui a été généré automatiquement.
Après qu’un utilisateur a créé un fragment de contenu reposant sur le modèle d’article, il peut être interrogé via GraphQL. Vous trouverez des exemples à la section Exemples de Requêtes (basée sur un modèle de structure de fragment de contenu à utiliser avec GraphQL).
Dans GraphQL pour AEM, le schéma est flexible. Cela signifie qu’il est généré automatiquement à chaque fois qu’un modèle de fragment de contenu est créé, mis à jour ou supprimé. Les caches de schémas de données sont également actualisés lorsque vous mettez à jour un modèle de fragment de contenu.
Le service Sites GraphQL écoute (en arrière-plan) toutes les modifications apportées à un modèle de fragment de contenu. Lorsque des mises à jour sont détectées, seule cette partie du schéma est régénérée. Cette optimisation permet de gagner du temps et de garantir la stabilité.
Par exemple, si vous :
Installez un package contenant Content-Fragment-Model-1
et Content-Fragment-Model-2
:
Model-1
et Model-2
seront générés.Puis modifiez Content-Fragment-Model-2
:
Seul le type Model-2
GraphQL sera mis à jour.
Alors que Model-1
restera le même.
Il est important de le noter si vous souhaitez effectuer des mises à jour en bloc sur les modèles de fragments de contenu via l’API REST, ou autrement.
Le schéma est desservi par le même point d’entrée que les requêtes GraphQL, le client gérant le fait que le schéma est appelé avec l’extension GQLschema
. Par exemple, l’exécution d’une requête GET
simple sur /content/cq:graphql/global/endpoint.GQLschema
entraîne la sortie du schéma avec le type de contenu : text/x-graphql-schema;charset=iso-8859-1
.
Le schéma comporte des champs individuels de deux catégories de base :
Champs que vous générez.
Une sélection de types de champs est utilisée pour créer des champs en fonction de la configuration du modèle de fragment de contenu. Les noms des champs proviennent du champ Nom de la propriété du Type de données.
GraphQL pour AEM génère également un certain nombre de champs d’assistance.
Ils servent à identifier un fragment de contenu ou à obtenir plus d’informations sur un fragment.
GraphQL pour AEM prend en charge une liste de types. Tous les types de données de modèles de fragments de contenu pris en charge et les types GraphQL correspondants sont représentés :
Modèle de fragment de contenu – Type de données | Type GraphQL | sa description ; |
---|---|---|
Une seule ligne de texte | Chaîne, [Chaîne] | Utilisé pour les chaînes simples telles que les noms d’auteurs, les noms d’emplacements, etc… |
Plusieurs lignes de texte | Chaîne | Utilisé pour générer du texte, tel que le corps d’un article |
Nombre | Flottant, [Flottant] | Utilisé pour afficher le nombre à virgule flottante et les nombres réguliers |
Booléen | Booléen | Utilisé pour afficher les cases à cocher → simples instructions vrai/faux |
Date et heure | Calendrier | Utilisé pour afficher la date et l’heure au format ISO 8086 |
Énumération | Chaîne | Utilisé pour afficher une option à partir d’une liste d’options définies lors de la création du modèle |
Balises | [Chaîne] | Utilisé pour afficher une liste de chaînes représentant les balises utilisées dans AEM |
Référence de contenu | Chaîne | Utilisé pour afficher le chemin vers une autre ressource dans AEM |
Référence du fragment | Un type de modèle | Utilisé pour référencer un autre fragment de contenu d’un certain type de modèle, défini lors de la création du modèle |
Outre les types de données des champs générés par l’utilisateur, GraphQL pour AEM génère également un certain nombre de champs d’assistance afin de faciliter l’identification d’un fragment de contenu ou de fournir des informations supplémentaires sur un fragment de contenu.
Le champ de chemin est utilisé comme identificateur dans GraphQL. Il représente le chemin d’accès de la ressource de fragment de contenu dans le référentiel AEM. Nous l’avons choisi comme identificateur d’un fragment de contenu, car il :
Le code suivant affiche les chemins de tous les fragments de contenu créés à partir du modèle de fragment de contenu Person
.
{
personList {
items {
_path
}
}
}
Pour récupérer un fragment de contenu unique d’un type spécifique, vous devez commencer par déterminer son chemin d’accès. par exemple :
{
personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
item {
_path
firstName
name
}
}
}
Voir Exemple de Requête - Un fragment de ville spécifique unique.
Par le biais de GraphQL, AEM expose également les métadonnées d’un fragment de contenu. Les métadonnées sont les informations qui décrivent un fragment de contenu, comme le titre d’un fragment de contenu, le chemin d’accès à la miniature, la description d’un fragment de contenu, la date de création, etc.
Les métadonnées étant générées par l’éditeur de schémas et n’ayant donc pas de structure spécifique, le type TypedMetaData
GraphQL a été implémenté pour exposer les métadonnées d’un fragment de contenu. TypedMetaData
expose les informations regroupées selon les types scalaires suivants :
Champ |
---|
stringMetadata:[StringMetadata]! |
stringArrayMetadata:[StringArrayMetadata]! |
intMetadata:[IntMetadata]! |
intArrayMetadata:[IntArrayMetadata]! |
floatMetadata:[FloatMetadata]! |
floatArrayMetadata:[FloatArrayMetadata]! |
booleanMetadata:[BooleanMetadata]! |
booleanArrayMetadata:[booleanArrayMetadata]! |
calendarMetadata:[CalendarMetadata]! |
calendarArrayMetadata:[CalendarArrayMetadata]! |
Chaque type scalaire représente soit une paire nom-valeur unique, soit un tableau de paires nom-valeur, où la valeur d’une paire est du type dans lequel elle a été regroupée.
Par exemple, si vous souhaitez récupérer le titre d’un fragment de contenu, nous savons que cette propriété est une propriété Chaîne et recherchons donc toutes les métadonnées Chaîne :
Pour rechercher des métadonnées :
{
personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
item {
_path
_metadata {
stringMetadata {
name
value
}
}
}
}
}
Vous pouvez afficher tous les types GraphQL de métadonnées si vous affichez le schéma GraphQL généré. Tous les types de modèle ont le même TypedMetaData
.
Différence entre les métadonnées normales et les métadonnées de tableau
Gardez à l’esprit que StringMetadata
et StringArrayMetadata
se rapportent tous deux à ce qui est stocké dans le référentiel et non à la façon dont vous les récupérez.
Par exemple, en appelant le champ stringMetadata
, vous recevriez un tableau de toutes les métadonnées stockées dans le référentiel comme String
et en appelant stringArrayMetadata
, vous recevriez un tableau de toutes les métadonnées stockées dans le référentiel comme String[]
.
Voir Modèle de recherche de métadonnées – Répertorier les métadonnées des prix intitulés GB.
Le champ _variations
a été implémenté pour simplifier la recherche de variations d’un fragment de contenu. Par exemple :
{
personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
item {
_variations
}
}
}
Voir Modèle de requête – Toutes les villes avec une variante nommée.
GraphQL permet de placer des variables dans la requête. Pour plus d’informations, voir la documentation GraphQL pour GraphiQL.
Par exemple, pour obtenir tous les fragments de contenu de type Article
présentant une variation spécifique, vous pouvez spécifier la variable variation
dans GraphiQL.
### query
query GetArticlesByVariation($variation: String!) {
articleList(variation: $variation) {
items {
_path
author
}
}
}
### in query variables
{
"variation": "uk"
}
Dans GraphQL, il est possible de modifier la requête en fonction de variables, nommées directives GraphQL.
Par exemple, vous pouvez inclure ici le champ adventurePrice
dans une requête pour tous les AdventureModels
, en fonction d’une variable includePrice
.
### query
query GetAdventureByType($includePrice: Boolean!) {
adventureList {
items {
adventureTitle
adventurePrice @include(if: $includePrice)
}
}
}
### in query variables
{
"includePrice": true
}
Vous pouvez également utiliser le filtrage dans vos requêtes GraphQL pour renvoyer des données spécifiques.
Le filtrage utilise une syntaxe basée sur des expressions et des opérateurs logiques.
Par exemple, la requête (de base) suivante filtres toutes les personnes dont le nom est Jobs
ou Smith
:
query {
personList(filter: {
name: {
_logOp: OR
_expressions: [
{
value: "Jobs"
},
{
value: "Smith"
}
]
}
}) {
items {
name
firstName
}
}
}
Pour d'autres exemples, voir :
détails des extensions GraphQL pour AEM
Modèles de requêtes utilisant ce modèle de contenu et de structure
Pour accéder au point de terminaison GraphQL à partir d’un site Web externe, vous devez configurer les éléments suivants :
Pour un aperçu détaillé de la politique de partage des ressources CORS dans AEM, voir Description du partage des ressources Cross-Origin (CORS).
Pour accéder au point de terminaison GraphQL, une stratégie CORS doit être configurée dans le référentiel Git du client. Pour ce faire, vous devez ajouter un fichier de configuration CORS OSGi approprié pour les points de terminaison souhaités.
Cette configuration doit spécifier une origine de site Web approuvée alloworigin
ou alloworiginregexp
pour laquelle l'accès doit être accordé.
Par exemple, pour accorder l’accès au point de terminaison GraphQL pour https://my.domain
, vous pouvez utiliser :
{
"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"
]
}
Si vous avez configuré un chemin d'accès à la vanité pour le point de terminaison, vous pouvez également l'utiliser dans allowedpaths
.
Outre la configuration CORS, un filtre de Parrain doit être configuré pour autoriser l’accès à partir d’hôtes tiers.
Pour ce faire, ajoutez un fichier de configuration de filtre de Parrain OSGi approprié qui :
allow.hosts
, soit allow.hosts.regexp
,Par exemple, pour accorder l’accès aux requêtes avec le Parrain my.domain
, vous pouvez :
{
"allow.empty":false,
"allow.hosts":[
"my.domain"
],
"allow.hosts.regexp":[
""
],
"filter.methods":[
"POST",
"PUT",
"DELETE",
"COPY",
"MOVE"
],
"exclude.agents.regexp":[
""
]
}
Il incombe au client de :
Tous les schémas GraphQL (dérivés des modèles de fragments de contenu qui ont été activés) sont lisibles par le point de terminaison GraphQL.
Cela signifie que vous devez vous assurer qu’aucune donnée sensible n’est disponible, car elle peut être divulguée de cette façon ; par exemple, cela inclut des informations qui peuvent être présentes sous forme de noms de champ dans la définition de modèle.
Voir Authentification pour les Requêtes GraphQL d'AEM distantes sur les fragments de contenu.
Questions soulevées :
Q : « En quoi l’API GraphQL pour AEM est-elle différente de l’API Query Builder ? »
Vous cherchez un tutoriel pratique ? Consultez le tutoriel complet Prise en main d’AEM découplé et de GraphQL illustrant comment créer et exposer du contenu à l’aide des API GraphQL d’AEM et consommé par une application externe, dans un scénario CMS découplé.