API AEM GraphQL pour l’utilisation des fragments de contenu graphql-api-for-use-with-content-fragments
Découvrez comment utiliser les fragments de contenu dans Adobe Experience Manager (AEM) as a Cloud Service avec l’API AEM GraphQL pour la diffusion de contenu en mode découplé.
L’API GraphQL d’AEM as a Cloud Service 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 :
- en évitant les demandes d’API itératives comme avec REST ;
- en veillant à ce que la diffusion soit limitée aux exigences spécifiques ;
- en permettant de diffuser en bloc exactement ce qui est nécessaire pour le rendu en réponse à une seule requête d’API.
- AEM Commerce utilise les données d’une plateforme commerciale par le biais de GraphQL.
- Les fragments de contenu d’AEM fonctionnent conjointement avec l’API AEM GraphQL (une implémentation personnalisée, basée sur GraphQL standard), pour fournir du contenu structuré à utiliser dans vos applications.
L’API GraphQL graphql-api
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és en interne par Facebook en 2012 avant d’être rendus open source 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’entreprises de toutes tailles… »
Voir GraphQL Foundation.
Pour plus d’informations sur l’API GraphQL, voir les sections suivantes (parmi de nombreuses autres ressources) :
La mise en œuvre GraphQL pour AEM repose sur la bibliothèque Java GraphQL standard. Voir :
Terminologie GraphQL graphql-terminology
GraphQL utilise les éléments suivants :
-
- Les schémas sont générés par AEM en fonction des modèles de fragment de contenu.
- Grâce à vos schémas, GraphQL présente les types et les opérations autorisés pour l’implémentation de GraphQL pour AEM.
-
-
Le 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 d’entrée GraphQL pour plus de détails.
-
Voir la Présentation de GraphQL (GraphQL.org) pour des détails complets, y compris les Bonnes pratiques.
Types de requêtes GraphQL graphql-query-types
GraphQL permet de réaliser des requêtes pour renvoyer, au choix :
-
Une entrée unique
-
Une liste d’entrées
AEM fournit des fonctionnalités de conversion des requêtes (des deux types) en Requêtes persistantes, qui peuvent être mises en cache par Dispatcher et le réseau CDN.
Bonnes pratiques en matière de requêtes GraphQL (Dispatcher et réseau CDN) graphql-query-best-practices
Il est recommandé d’utiliser les Requêtes persistantes sur les instances de publication en raison des avantages suivants :
- Elles sont mises en cache.
- Elles sont gérées de manière centralisée par AEM as a Cloud Service.
Les requêtes GraphQL utilisant des requêtes POST ne sont pas recommandées, car elles ne sont pas mises en cache. Par conséquent, dans une instance par défaut, Dispatcher est configuré pour bloquer ces requêtes.
Bien que GraphQL prenne également en charge les requêtes de GET, celles-ci peuvent atteindre des limites (par exemple, la longueur de l’URL) qui peuvent être évitées à l’aide des requêtes persistantes.
Voir Activer le cache des requêtes persistantes pour plus de détails.
- créer une variable d’environnement Cloud Manager appelée
ENABLE_GRAPHQL_ENDPOINT
- avec la valeur
true
.
IDE GraphiQL graphiql-ide
Vous pouvez tester et déboguer des requêtes GraphQL à l’aide de l’IDE GraphiQL.
Cas d’utilisation pour la création, la prévisualisation et la publication use-cases-author-preview-publish
Les cas d’utilisation peuvent dépendre du type d’environnement AEM as a Cloud Service :
-
Environnement de publication, utilisé pour :
- Réaliser des requête de données pour l’application JS (cas d’utilisation standard)
-
Environnement de prévisualisation, utilisé pour :
- Prévisualiser des requêtes avant le déploiement dans l’environnement de publication
- Réaliser des requête de données pour l’application JS (cas d’utilisation standard)
- Prévisualiser des requêtes avant le déploiement dans l’environnement de publication
-
Environnement de création, utilisé pour :
-
Réaliser des requêtes de données à des fins de gestion de contenu :
- GraphQL dans AEM as a Cloud Service est actuellement une API en lecture seule.
- L’API REST peut être utilisée pour les opérations CR(u)D.
-
Autorisations permission
Les autorisations sont celles requises pour accéder aux ressources.
Les requêtes GraphQL sont exécutées avec l’autorisation de l’utilisateur ou utilisatrice AEM de la requête sous-jacente. Si l’utilisateur ou l’utilisatrice ne dispose pas d’un accès en lecture à certains fragments (stockés en tant que ressources), ils ne feront pas partie du jeu de résultats.
En outre, l’utilisateur doit avoir accès à un point de terminaison GraphQL pour pouvoir exécuter des requêtes GraphQL.
Génération de schémas schema-generation
GraphQL est une API fortement typée, ce qui signifie que 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. Pour ce faire, un client doit récupérer le schéma, qui contient tous les types nécessaires à une requête.
Pour les fragments de contenu, les schémas GraphQL (structure et types) reposent sur des Modèles de fragments de contenu activés et leurs types de données
Par exemple, si un utilisateur ou une utilisatrice crée un modèle de fragment de contenu appelé Article
, alors AEM génère un ArticleModel
de type GraphQL. Les champs de ce type correspondent aux champs et aux types de données définis dans le modèle. AEM crée également des points d’entrée pour les requêtes qui opèrent sur ce type, comme articleByPath
ou articleList
.
-
Un modèle de fragment de contenu :
-
Le 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
etreferencearticle
. -
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, les « champs d’aide »
_path
,_metadata
et_variations
).
-
-
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.
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 d’apporter de la stabilité.
Par exemple, si vous :
-
Installez un package contenant
Content-Fragment-Model-1
etContent-Fragment-Model-2
:- Les types GraphQL pour
Model-1
etModel-2
sont générés.
- Les types GraphQL pour
-
Puis modifiez
Content-Fragment-Model-2
:-
Seul le type
Model-2
GraphQL sera mis à jour. -
Alors que
Model-1
restera le même.
-
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
.
Génération de schémas – Modèles dépubliés schema-generation-unpublished-models
Lorsque des fragments de contenu sont imbriqués, il se peut qu’un modèle de fragment de contenu parent soit publié, mais pas un modèle référencé.
Dans ce cas, AEM génère un schéma incomplet pour le modèle de fragment de contenu parent. Cela signifie que la référence au fragment, qui dépend du modèle dépublié, est supprimée du schéma.
Champs fields
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 données 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é de l’onglet Type de données.
- Prenez également en compte le paramètre Rendre en tant que, car les utilisateurs et utilisatrices peuvent configurer certains types de données. Par exemple, un champ de texte d’une seule ligne peut être configuré pour contenir plusieurs textes d’une seule ligne en sélectionnant
multifield
dans la liste déroulante.
- Prenez également en compte le paramètre Rendre en tant que, car les utilisateurs et utilisatrices peuvent configurer certains types de données. Par exemple, un champ de texte d’une seule ligne peut être configuré pour contenir plusieurs textes d’une seule ligne en sélectionnant
-
GraphQL pour AEM génère également plusieurs champs d’assistance.
Types de données data-types
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 :
String
, [String]
String
, [String]
Float
, [Float]
Boolean
Calendar
onlyDate
, onlyTime
, dateTime
String
[String]
String
, [String]
String
, [String]
Champ unique :
Model
- Type de modèle, référencé directementMultichamp, avec un type référencé :
[Model]
- Tableau de type Model
, référencé directement depuis le tableauMultichamp, avec plusieurs types référencés :
[AllFragmentModels]
- Tableau de tous les types de modèles, référencé depuis un tableau avec type unionChamp unique :
Model
- Type de modèle, référencé directementMultichamp, avec un type référencé :
[Model]
- Tableau de type Model
, référencé directement depuis le tableauMultichamp, avec plusieurs types référencés :
[AllFragmentModels]
- Tableau de tous les types de modèles, référencé depuis un tableau avec type unionChamps d’assistant helper-fields
Outre les types de données pour les champs générés par l’utilisateur, GraphQL pour AEM génère également plusieurs champs helper pour aider à identifier un fragment de contenu ou fournir des informations supplémentaires sur un fragment de contenu.
Ces champs d’assistance sont précédés d’un _
pour distinguer ce qui a été défini par l’utilisateur ou l’utilisatrice de ce qui a été généré automatiquement.
Chemin d’accès path
Le champ de chemin est utilisé comme identificateur dans AEM 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 :
- est unique dans AEM ;
- peut facilement être récupéré.
Le code suivant affiche les chemins de tous les fragments de contenu créés à partir du modèle de fragment de contenu Author
, comme décrit dans le tutoriel WKND.
{
authorList {
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 :
{
authorByPath(_path: "/content/dam/wknd-shared/en/contributors/sofia-sj-berg") {
item {
_path
firstName
lastName
}
}
}
Voir Exemple de requête – Un fragment de ville unique et spécifique.
ID (UUID) id-uuid
Le champ Identifiant est également utilisé comme identifiant dans AEM GraphQL. Il représente le chemin d’accès de la ressource Fragment de contenu dans le référentiel AEM, mais au lieu de contenir le chemin d’accès réel, il contient un UUID représentant la ressource. Nous l’avons choisi comme identificateur d’un fragment de contenu, car il :
- est unique dans AEM ;
- peut être facilement récupéré,
- ne change pas lorsque la ressource est déplacée.
L’UUID d’un fragment de contenu et d’un fragment de contenu référencé, ou ressource, peut être renvoyé via la propriété JSON _id
.
{
articleList {
items {
_id
_path
}
}
}
Métadonnées metadata
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 :
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 :
{
authorByPath(_path: "/content/dam/wknd-shared/en/contributors/sofia-sj-berg") {
item {
_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
.
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.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 Exemple de requête pour les métadonnées – Répertorier les métadonnées des prix intitulés GB.
Variations variations
Le champ _variations
a été implémenté pour simplifier la recherche de variations d’un fragment de contenu. Par exemple :
{
authorByPath(_path: "/content/dam/wknd-shared/en/contributors/ian-provo") {
item {
_variations
}
}
}
_variations
ne contient pas de variation master
, car techniquement les données d’origine (référencées comme Principal dans l’interface utilisateur) ne sont pas considérées comme une variation explicite.Voir Exemple de requête – Toutes les villes avec une variation nommée.
Variables GraphQL graphql-variables
GraphQL permet de placer des variables dans la requête. Pour plus d’informations, voir Documentation GraphQL pour les variables.
Par exemple, pour obtenir tous les fragments de contenu de type Author
dans une variation spécifique (si disponible), vous pouvez spécifier l’argument variation
dans GraphiQL.
Requête :
query($variation: String!) {
authorList(variation: $variation) {
items {
_variation
lastName
firstName
}
}
}
Variables de requête :
{
"variation": "another"
}
Cette requête renverra la liste complète des auteurs. Les auteurs qui n’ont pas la variation another
reviendront aux données d’origine (_variation
indiquera master
dans ce cas).
Appliquez un filtre si vous souhaitez limiter la liste aux céateurs et créatrices qui fournissent la variation spécifiée (et ignorer les créateurs et créatrices qui reviennent aux données d’origine) :
query($variation: String!) {
authorList(variation: $variation, filter: {
_variation: {
_expressions: {
value: $variation
}
}
}) {
items {
_variation
lastName
firstName
}
}
}
Directives GraphQL graphql-directives
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
.
Requête :
query GetAdventureByType($includePrice: Boolean!) {
adventureList {
items {
title
price @include(if: $includePrice)
}
}
}
Variables de requête :
{
"includePrice": true
}
Filtrage filtering
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.
La partie la plus atomique est une expression unique qui peut être appliquée au contenu d’un certain champ. Il compare le contenu du champ avec une valeur constante donnée.
Par exemple, l’expression
{
value: "some text"
_op: EQUALS
}
compare le contenu du champ à la valeur some text
et réussit si le contenu est égal à la valeur. Dans le cas contraire, l’expression échouera.
Les opérateurs suivants peuvent être utilisés pour comparer les champs à une certaine valeur :
EQUALS
String
, ID
, Boolean
EQUALS_NOT
String
, ID
CONTAINS
String
{ value: "mas", _op: CONTAINS }
correspondra à Christmas
, Xmas
, master
…).CONTAINS_NOT
String
STARTS_WITH
ID
{ value: "/content/dam/", _op: STARTS_WITH
correspondra à /content/dam/path/to/fragment
, mais pas à /namespace/content/dam/something
.EQUAL
Int
, Float
UNEQUAL
Int
, Float
GREATER
Int
, Float
GREATER_EQUAL
Int
, Float
LOWER
Int
, Float
LOWER_EQUAL
Int
, Float
AT
Calendar
, Date
, Time
NOT_AT
Calendar
, Date
, Time
BEFORE
Calendar
, Date
, Time
AT_OR_BEFORE
Calendar
, Date
, Time
AFTER
Calendar
, Date
, Time
AT_OR_AFTER
Calendar
, Date
, Time
Certains types vous permettent également de spécifier des options supplémentaires qui modifient la manière dont une expression est évaluée :
_ignoreCase
String
time
correspond à TIME
, time
, tImE
, …_sensitiveness
Float
float
soient considérées comme identiques (pour contourner les limitations techniques en raison de la représentation interne des valeurs float
). Cette option n’est pas recommandée en raison de son impact négatif sur les performances.Les expressions peuvent être combinées à un jeu à l’aide d’un opérateur logique (_logOp
) :
OR
: le jeu d’expressions réussit si au moins une expression réussit.AND
: le jeu d’expressions réussit si toutes les expressions réussissent (par défaut).
Chaque champ peut être filtré par son propre jeu d’expressions. Les jeux d’expressions de tous les champs mentionnés dans l’argument de filtre seront finalement combinés par leur propre opérateur logique.
Une définition de filtre (transmise comme l’argument filter
dans une requête) contient les éléments suivants :
- Une sous-définition pour chaque champ (le champ est accessible par son nom, par exemple, il y a un champ
lastName
dans le filtre pour le champlastName
dans le type Données (champ)) - Chaque sous-définition contient le tableau
_expressions
, qui fournit le jeu d’expressions, ainsi que le champ_logOp
, qui définit l’opérateur logique avec lequel les expressions doivent être combinées. - Chaque expression est définie par la valeur (champ
value
) et l’opérateur (champ_operator
) auxquels le contenu d’un champ doit être comparé.
Vous pouvez omettre _logOp
si vous souhaitez combiner des éléments avec AND
et _operator
si vous souhaitez vérifier l’égalité, car il s’agit des valeurs par défaut.
L’exemple suivant illustre une requête complète qui filtre toutes les personnes dont le lastName
est Provo
ou contenant sjö
, quel que soit le cas :
{
authorList(filter: {
lastname: {
_logOp: OR
_expressions: [
{
value: "sjö",
_operator: CONTAINS,
_ignoreCase: true
},
{
value: "Provo"
}
]
}
}) {
items {
lastName
firstName
}
}
}
Il n’est pas recommandé de filtrer les champs imbriqués (bien que cela soit possible), car cela peut entraîner des problèmes de performances.
Pour accéder à 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
- et Modèle de contenu et de structure préparé pour une utilisation dans des modèles de requêtes
Tri sorting
Cette fonctionnalité vous permet de trier les résultats de la requête en fonction d’un champ spécifié.
Les critères de tri sont les suivants :
-
il s’agit d’une liste de valeurs séparées par des virgules représentant le chemin du champ,
- le premier champ de la liste définit l’ordre de tri principal, le second champ est utilisé si deux valeurs du critère de tri principal sont égales, le troisième si les deux premiers critères sont égaux, etc.
- notation pointillée, c’est-à-dire field1.subfield.subfield, etc…
-
avec un sens d’ordre optionnel,
- ASC (croissant) ou DESC (décroissant) ; la valeur par défaut est ASC,
- le sens d’ordre peut être spécifié par champ : vous pouvez trier un champ par ordre croissant et un autre par ordre décroissant (name, firstName DESC).
Par exemple :
query {
authorList(sort: "lastName, firstName") {
items {
firstName
lastName
}
}
}
Un autre exemple :
{
authorList(sort: "lastName DESC, firstName DESC") {
items {
lastName
firstName
}
}
}
Vous pouvez également trier un champ dans un fragment imbriqué au format nestedFragmentname.fieldname
.
Par exemple :
query {
articleList(sort: "authorFragment.lastName") {
items {
title
authorFragment {
firstName
lastName
birthDay
}
slug
}
}
}
Pagination paging
Cette fonctionnalité vous permet d’effectuer une pagination sur les types de requête qui renvoient une liste. Deux méthodes sont proposées :
offset
etlimit
dans une requêteList
first
etafter
dans une requêtePaginated
Requête de liste : « offset » et « limit » list-offset-limit
Dans une requête ...List
, vous pouvez utiliser offset
et limit
pour renvoyer un sous-ensemble spécifique de résultats :
offset
: spécifie le premier jeu de données à renvoyer.limit
: spécifie le nombre maximal de jeux de données à renvoyer.
Par exemple, pour obtenir la page de résultats contenant jusqu’à cinq articles, en commençant par le cinquième article de la liste complète des résultats, effectuez l’opération suivante :
query {
articleList(offset: 5, limit: 5) {
items {
authorFragment {
lastName
firstName
}
}
}
}
-
La pagination nécessite un ordre de tri stable pour fonctionner correctement sur plusieurs requêtes demandant différentes pages du même jeu de résultats. Par défaut, il utilise le chemin d’accès au référentiel de chaque élément du jeu de résultats pour s’assurer que l’ordre est toujours le même. Si un ordre de tri différent est utilisé et si ce tri ne peut pas être effectué au niveau de la requête JCR, cela a un impact sur les performances, car le jeu complet de résultats doit être chargé en mémoire avant que les pages puissent être déterminées.
-
Plus le décalage est élevé, plus il faudra de temps pour ignorer les éléments du jeu complet de résultats de la requête JCR. Une autre solution pour les jeux de résultats volumineux consiste à utiliser la requête paginée avec la méthode
first
etafter
.
Requête paginée : « first » et « after » paginated-first-after
Le type de requête ...Paginated
utilise la plupart des fonctionnalités du type de requête ...List
(filtrage et tri), mais au lieu d’utiliser les arguments offset
/limit
, il utilise les arguments first
/after
tels que définis dans la Spécification des connexions basées sur le curseur GraphQL. Consultez une introduction moins formelle dans la Présentation de GraphQL.
first
: lesn
premiers éléments à renvoyer.
La valeur par défaut est50
.
La valeur maximale est100
.after
: le curseur qui détermine le début de la page demandée. Notez que l’élément représenté par le curseur n’est pas inclus dans le jeu de résultats. Le curseur d’un élément est déterminé par le champcursor
de la structureedges
.
Par exemple, vous pouvez afficher la page des résultats contenant jusqu’à cinq aventures, à partir de l’élément donné du curseur dans la liste complète des résultats :
query {
adventurePaginated(first: 5, after: "ODg1MmMyMmEtZTAzMy00MTNjLThiMzMtZGQyMzY5ZTNjN2M1") {
edges {
cursor
node {
title
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
-
Par défaut, la pagination utilise l’UUID du nœud du référentiel représentant le fragment afin de s’assurer que l’ordre des résultats est toujours le même. Lorsque
sort
est utilisé, l’UUID est implicitement utilisé pour assurer un tri unique, même pour deux éléments disposant de clés de tri identiques. -
En raison de contraintes techniques internes, les performances se dégradent si le tri et le filtrage sont appliqués aux champs imbriqués. Il est donc recommandé d’utiliser des champs de filtrage/tri stockés au niveau racine. Il s’agit également de la méthode recommandée si vous souhaitez interroger des jeux de résultats paginés volumineux.
Diffusion d’images optimisées pour le web dans des requêtes GraphQL web-optimized-image-delivery-in-graphql-queries
La diffusion d'images optimisées pour le Web permet d'utiliser une requête Graphql pour :
-
Demande d’une URL à une image de ressource DAM (référencée par une référence de contenu)
-
Transmettez des paramètres avec la requête, de sorte qu’un rendu spécifique de l’image soit automatiquement généré et renvoyé.
note note NOTE Le rendu spécifié n’est pas stocké dans AEM Assets. Le rendu est généré et conservé dans le cache pendant une courte période. -
Renvoyer l’URL dans le cadre de la diffusion JSON
Vous pouvez utiliser AEM pour :
- Transmettre la Diffusion d’images optimisées pour le web dans les requêtes GraphQL.
Cela signifie que les commandes sont appliquées lors de l’exécution de la requête, de la même manière que les paramètres d’URL sur les demandes GET pour ces images.
Vous pouvez ainsi créer dynamiquement des rendus d’image pour la diffusion JSON, ce qui évite d’avoir à créer et stocker manuellement ces rendus dans le référentiel.
La solution de GraphQL vous permet :
-
Demander une URL : utilisez
_dynamicUrl
sur la référenceImageRef
-
Transmettez les paramètres : ajoutez
_assetTransform
à l’en-tête de liste où vos filtres sont définis.
_dynamicUrl
: ressource DAM_dmS7Url
: une ressource Dynamic Media
_dmS7Url
sera null
. Voir Diffusion de ressources Dynamic Media par URL dans les requêtes GraphQL.Structure de la demande de transformation structure-transformation-request
AssetTransform
(_assetTransform
) est utilisé pour effectuer les demandes de transformation d’URL.
La structure et la syntaxe sont les suivantes :
-
format
: une énumération avec tous les formats pris en charge par son extension : GIF, PNG, PNG8, JPG, PJPG, BJPG, WEBP, WEBPLL ou WEBPLY ; -
seoName
: une chaîne qui est utilisée comme nom de fichier au lieu du nom de nœud ; -
crop
: une sous-structure d’image, si la largeur ou la hauteur est omise alors la hauteur ou la largeur est utilisée comme même valeur ;xOrigin
: l’origine x de l’image, obligatoire ;yOrigin
: l’origine y de l’image, obligatoire ;width
: la largeur de l’image ;height
: la hauteur de l’image ;
-
size
: une sous-structure de dimension, si la largeur ou la hauteur est omise alors la hauteur ou la largeur est utilisée comme même valeur ;width
: la largeur de la dimension ;height
: la hauteur de la dimension ;
-
rotation
: une énumération de toutes les rotations prises en charge : R90, R180, R270 ; -
flip
: une énumération de HORIZONTAL, VERTICAL, HORIZONTAL_AND_VERTICAL ; -
quality
: un entier compris entre 1 et 100 indiquant le pourcentage de la qualité de l’image ; -
width
: un entier qui définit la largeur de l’image de sortie, mais qui est ignoré par le générateur d’images ; -
preferWebp
: une valeur booléenne qui indique si webp est préférable (la valeur par défaut est false).
La transformation d’URL est disponible pour tous les types de requête : par chemin, liste ou paginé.
Diffusion d’images optimisées pour le web avec des paramètres complets web-optimized-image-delivery-full-parameters
Voici un exemple de requête avec un ensemble complet de paramètres :
{
articleList(
_assetTransform: {
format:GIF
seoName:"test"
crop:{
xOrigin:10
yOrigin:20
width:50
height:45
}
size:{
height:100
width:200
}
rotation:R90
flip:HORIZONTAL_AND_VERTICAL
quality:55
width:123
preferWebp:true
}
) {
items {
_path
featuredImage {
... on ImageRef {
_dynamicUrl
}
}
}
}
}
Diffusion d’images optimisées pour le web avec une variable de requête unique web-optimized-image-delivery-single-query-variable
L’exemple suivant illustre l’utilisation d’une variable de requête unique :
query ($seoName: String!) {
articleList(
_assetTransform: {
format:GIF
seoName:$seoName
crop:{
xOrigin:10
yOrigin:20
width:50
height:45
}
size:{
height:100
width:200
}
rotation:R90
flip:HORIZONTAL_AND_VERTICAL
quality:55
width:123
preferWebp:true
}
) {
items {
_path
featuredImage {
... on ImageRef {
_dynamicUrl
}
}
}
}
}
Diffusion d’images optimisées pour le web avec plusieurs variables de requête web-optimized-image-delivery-multiple-query-variables
L’exemple suivant illustre l’utilisation de plusieurs variables de requête :
query ($seoName: String!, $format: AssetTransformFormat!) {
articleList(
_assetTransform: {
format:$format
seoName:$seoName
crop:{
xOrigin:10
yOrigin:20
width:50
height:45
}
size:{
height:100
width:200
}
rotation:R90
flip:HORIZONTAL_AND_VERTICAL
quality:55
width:123
preferWebp:true
}
) {
items {
_path
featuredImage {
... on ImageRef {
_dynamicUrl
}
}
}
}
}
Demande de diffusion d’images optimisées pour le web par URL web-optimized-image-delivery-request-url
Si vous enregistrez votre requête en tant que requête persistante (par exemple, avec le nom dynamic-url-x
) vous pouvez alors exécuter directement la requête persistante.
Par exemple, pour exécuter directement les exemples précédents (enregistrés en tant que requêtes persistantes), utilisez les URL suivantes :
-
Paramètre unique ; Requête persistante nommée
dynamic-url-x
-
http://localhost:4502/graphql/execute.json/wknd-shared/dynamic-url-x;seoName=xxx
La réponse se présente comme suit :
-
-
Paramètres multiples ; Requête persistante nommée
dynamic
-
http://localhost:4502/graphql/execute.json/wknd-shared/dynamic;seoName=billiboy;format=GIF;
note caution CAUTION Le chiffre ;
est obligatoire pour terminer correctement la liste des paramètres.
-
Limites de la diffusion d’images optimisée pour le web web-optimized-image-delivery-limitations
Les restrictions suivantes s’appliquent :
-
Modificateurs appliqués à toutes les images faisant partie de la requête (paramètres globaux)
-
Mise en cache des en-têtes
- Aucune mise en cache sur l’instance de création
- Mise en cache lors de la publication : 10 minutes max. (non modifiable par les clients).
Diffusion de ressources Dynamic Media par URL dans les requêtes GraphQL dynamic-media-asset-delivery-by-url
GraphQL pour les fragments de contenu AEM vous permet de demander une URL à une ressource Dynamic Media (Scene7) AEM (référencée par une référence de contenu).
La solution de GraphQL vous permet :
-
d’utiliser
_dmS7Url
sur la référenceImageRef
; -
utiliser
_dmS7Url
sur plusieurs références ;ImageRef
,MultimediaRef
etDocumentRef
-
Utilisation de
_dmS7Url
avec la fonctionnalité de recadrage intelligent-
La propriété
_smartCrops
expose les configurations de recadrage intelligent disponibles pour une ressource spécifique.
-
dam:scene7File
et dam:scene7Domain
aux métadonnées de la ressource lors de sa création._dmS7Url
: une ressource Dynamic Media_dynamicUrl
: ressource DAM
_dynamicURL
sera null
. Voir diffusion d’images optimisée pour le web dans les requêtes GraphQL.Exemple de requête pour la diffusion de ressources Dynamic Media par URL - Référence d’image sample-query-dynamic-media-asset-delivery-by-url-imageref
Voici un exemple de requête :
- pour plusieurs fragments de contenu de type
team
etperson
, renvoyant unImageRef
query allTeams {
teamList {
items {
_path
title
teamMembers {
fullName
profilePicture {
__typename
... on ImageRef{
_dmS7Url
height
width
}
}
}
}
}
}
Exemple de requête pour la diffusion de ressources Dynamic Media par URL - Références multiples sample-query-dynamic-media-asset-delivery-by-url-multiple-refs
Voici un exemple de requête :
- pour plusieurs fragments de contenu de type
team
etperson
, renvoyant unImageRef
,MultimediaRef
etDocumentRef
:
query allTeams {
teamList {
items {
_path
title
teamMembers {
fullName
profilePicture {
__typename
... on ImageRef{
_dmS7Url
height
width
}
}
featureVideo {
__typename
... on MultimediaRef{
_dmS7Url
size
}
}
about-me {
__typename
... on DocumentRef{
_dmS7Url
_path
}
}
}
}
}
}
Exemple de requête pour la diffusion de ressources Dynamic Media par URL - avec recadrage intelligent sample-query-dynamic-media-asset-delivery-by-url-smart-crop
Voici un exemple de requête :
- pour exposer les configurations de recadrage intelligent disponibles pour les ressources demandées
query allTeams {
teamList {
items {
title
teamMembers {
profilePicture {
... on ImageRef {
height
width
_dmS7Url
_smartCrops {
width
height
name
}
}
}
}
}
}
}
GraphQL pour AEM – Résumé des extensions graphql-extensions
Le fonctionnement de base des requêtes avec GraphQL pour AEM est conforme à la spécification GraphQL standard. Pour les requêtes GraphQL avec AEM, il existe quelques extensions :
-
Si vous avez besoin d’un seul résultat :
- utiliser le nom du modèle ; par exemple, city
-
Si vous prévoyez une liste de résultats :
- Ajoutez
List
au nom du modèle ; par exemple,cityList
- Voir Exemple de requête – Toutes les informations sur toutes les villes
Vous pouvez ensuite :
-
ASC
: croissantDESC
: décroissant
-
Renvoyer une page de résultats à l’aide de l’une des méthodes suivantes :
-
Voir Exemple de requête – Toutes les informations sur toutes les villes.
- Ajoutez
-
Le filtre
includeVariations
est inclus dans les types de requêteList
etPaginated
. Pour récupérer les variations du fragment de contenu dans les résultats de la requête, vous devez définir le filtreincludeVariations
surtrue
.- Voir Exemple de requête pour plusieurs fragments de contenu et leurs variations dans un modèle donné
note caution CAUTION Le filtre includeVariations
et le champ généré par le système_variation
ne peuvent pas être utilisés ensemble dans la même définition de requête. -
Si vous souhaitez utiliser un OU logique :
- Utilisez
_logOp: OR
- Voir Exemple de requête – Toutes les personnes qui portent le nom « Jobs » ou « Smith »
- Utilisez
-
L’opérateur logique ET existe également, mais est (souvent) implicite
-
Vous pouvez appliquer des requêtes aux noms de champ qui correspondent aux champs du modèle de fragment de contenu.
-
Outre les champs de votre modèle, il existe certains champs générés par le système (précédés d’un trait de soulignement) :
-
Pour le contenu :
-
_locale
: pour afficher la langue ; basé sur Language Manager -
_metadata
: pour afficher les métadonnées de votre fragment -
_model
: autoriser l’interrogation d’un modèle de fragment de contenu (chemin et titre) -
_path
: chemin d’accès au fragment de contenu dans le référentiel. -
_id
: UUID de votre fragment de contenu dans le référentiel -
_reference
: pour afficher les références ; y compris les références intégrées dans l’éditeur de texte enrichi -
_variation
: pour afficher des variantes spécifiques dans votre fragment de contenunote note NOTE Si la variation donnée n’existe pas pour un fragment de contenu, la variation principale est renvoyée comme valeur (de secours) par défaut. note caution CAUTION Vous ne pouvez pas utiliser le champ généré par le système _variation
avec le filtreincludeVariations
.
-
-
Pour la diffusion d'images :
-
_authorURL
: URL complète de la ressource image sur l’auteur AEM -
_publishURL
: URL complète de la ressource image sur AEM Publish -
Pour la diffusion d’image optimisée pour le web (de ressources DAM) :
-
_dynamicUrl
: URL complète de la ressource DAM optimisée pour le web sur la référenceImageRef
note note NOTE _dynamicUrl
est l’URL préférée à utiliser pour les ressources DAM optimisées pour le web et doit remplacer_path
,_authorUrl
et_publishUrl
chaque fois que cela est possible. -
_assetTransform
: pour transmettre des paramètres sur l’en-tête de liste dans lequel vos filtres sont définis -
Voir :
-
-
_dmS7Url
: sur la référenceImageRef
pour la diffusion de l’URL vers une ressource Dynamic Media
-
-
_tags
: pour révéler les identifiants des fragments de contenu ou des variations contenant des balises ; il s’agit d’un tableau d’identifiantscq:tags
.- Reportez-vous à Exemple de requête : noms de toutes les villes balisées en tant qu’Escapades en ville.
- Reportez-vous à Exemple de requête pour les variations de fragments de contenu d’un modèle donné auxquelles est associée une balise spécifique.
- Voir Exemple de requête avec filtrage par identifiant de balises et excluant des variations
- Voir Exemple de requête avec filtrage par identifiant de balises et incluant des variations
note note NOTE Vous pouvez également interroger les balises en répertoriant les métadonnées d’un fragment de contenu. -
Et les opérations :
-
_operator
: pour appliquer des opérateurs spécifiques ;EQUALS
,EQUALS_NOT
,GREATER_EQUAL
,LOWER
,CONTAINS
,STARTS_WITH
-
_apply
: pour appliquer des conditions spécifiques ; par exempleAT_LEAST_ONCE
-
_ignoreCase
: pour ignorer la casse lors de l’application de la requête
-
-
-
Les types d’union GraphQL sont pris en charge :
-
Secours lors de l’interrogation de fragments imbriqués :
- Si une variation donnée n’existe pas dans un fragment imbriqué, la variation Principal est renvoyée.
Requête du point d’entrée GraphQL à partir d’un site web externe query-graphql-endpoint-from-external-website
Pour accéder au point d’entrée GraphQL à partir d’un site web externe, vous devez configurer les éléments suivants :
Authentification authentication
Voir Authentification pour les requêtes distantes AEM GraphQL sur les fragments de contenu.
Tests automatisés automated-testing
Lors de l’exécution d’un pipeline de déploiement dans AEM Cloud Manager, les tests automatisés sont exécutés pendant l’exécution du pipeline.
Pour fournir des résultats précis, votre environnement AEM as a Cloud Service Stage doit refléter votre environnement Production aussi près que possible. Ceci est particulièrement important pour le contenu.
Pour ce faire, utilisez l’'outil de copie de contenu🔗 d’'AEM as a Cloud Service pour copier le contenu de production dans l’environnement d’évaluation.
Limites limitations
Pour vous protéger contre les problèmes potentiels, vos requêtes sont soumises à des limitations par défaut :
- La requête ne peut pas contenir plus de 1 million (1 024x1 024) de caractères.
- La requête ne peut pas contenir plus de 15 000 jetons.
- La requête ne peut pas contenir plus de 200 000 jetons d’espace blanc.
À savoir également :
-
Une erreur de conflit de champ est renvoyée lorsque votre requête GraphQL contient des champs portant le même nom dans deux modèles (ou plus) et que les conditions suivantes sont remplies :
-
Dans les cas où :
- Deux (ou plusieurs modèles) sont utilisés comme références possibles, lorsqu’ils sont définis comme un Type de modèle autorisé dans la référence Fragment de contenu.
et :
- Ces deux modèles ont des champs ayant un nom commun. Cela signifie que le même nom apparaît dans les deux modèles.
et
- Ces champs sont de différents types de données.
-
Par exemple :
-
Lorsque deux fragments (ou plus) avec des modèles différents (par exemple,
M1
,M2
) sont utilisées comme références possibles (référence de contenu ou référence de fragment) à partir d’un autre fragment. Par exemple,Fragment1
MultiField/List
. -
Et ces deux fragments avec des modèles différents (
M1
,M2
) comportent des champs portant le même nom, mais avec des types différents.
Illustration :M1.Title
en tant queText
M2.Title
en tant queText/MultiField
-
Une erreur de conflit de champ se produira si la requête GraphQL contient le champ
Title
.
-
-
FAQ faqs
Questions soulevées :
-
Q : « En quoi l’API GraphQL pour AEM est-elle différente de l’API Query Builder ? »
- R : « L’API AEM GraphQL offre un contrôle total sur la sortie JSON et est une norme du secteur pour les requêtes de contenu.
AEM prévoit d’investir dans l’API AEM GraphQL. »
- R : « L’API AEM GraphQL offre un contrôle total sur la sortie JSON et est une norme du secteur pour les requêtes de contenu.
Tutoriel – Prise en main d’AEM découplé et de GraphQL tutorial
Vous cherchez un tutoriel pratique ? Consultez le tutoriel complet Prise en main d’AEM Headless 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é.