GraphQL API AEM voor gebruik met inhoudsfragmenten graphql-api-for-use-with-content-fragments
Leer hoe u inhoudsfragmenten in Adobe Experience Manager (AEM) kunt gebruiken met de AEM GraphQL API voor het leveren van inhoud zonder kop.
AEM GraphQL API die wordt gebruikt met Content Fragments is sterk gebaseerd op de standaard, open-source GraphQL API.
Door de GraphQL API in AEM te gebruiken, kunt u inhoudsfragmenten efficiënt aan JavaScript-clients leveren in CMS-implementaties zonder kop:
- Herhalende API-aanvragen voorkomen, zoals REST,
- ervoor zorgen dat de levering beperkt blijft tot de specifieke eisen;
- Het toestaan voor bulklevering van precies wat voor het teruggeven als antwoord op één enkele API vraag nodig is.
- AEM Commerce gebruikt gegevens van een Commerce-platform via GraphQL.
- AEM Content Fragments werken samen met de AEM GraphQL API (een aangepaste implementatie op basis van standaard GraphQL) voor gestructureerde inhoud voor gebruik in uw toepassingen.
Vereisten prerequisites
Klanten die GraphQL gebruiken, moeten het AEM Content Fragment installeren met GraphQL Index Package 1.0.5. Zie de Opmerkingen bij de release voor nadere bijzonderheden.
De GraphQL API graphql-api
GraphQL is:
-
"…een querytaal voor API's en een runtime voor het uitvoeren van deze query's met uw bestaande gegevens. GraphQL geeft een volledige en begrijpelijke beschrijving van de gegevens in uw API. Het geeft cliënten de macht om precies te vragen wat zij en niets meer nodig hebben, maakt het gemakkelijker om APIs in tijd te evolueren, en laat krachtige ontwikkelaarshulpmiddelen toe.".
Zie GraphQL.org
-
"…een open specificatie voor een flexibele API-laag. Plaats GraphQL over uw bestaande achtergronden zodat u producten sneller dan ooit kunt bouwen…".
Zie GraphQL verkennen.
-
"…een taal en specificatie voor gegevensquery die in 2012 intern door Facebook zijn ontwikkeld, voordat deze in 2015 openbaar is uitbesteed. Het biedt een alternatief voor op REST gebaseerde architecturen met als doel de productiviteit van ontwikkelaars te verhogen en de hoeveelheden overgedragen gegevens te minimaliseren. GraphQL wordt gebruikt in productie door honderden organisaties van elke omvang…"
Zie GraphQL Foundation.
Raadpleeg de volgende secties (onder andere over veel andere bronnen) voor meer informatie over de GraphQL API:
De GraphQL for AEM-implementatie is gebaseerd op de standaard GraphQL Java™-bibliotheek. Zie:
GraphQL Terminologie graphql-terminology
GraphQL gebruikt het volgende:
-
- Schema's worden gegenereerd door AEM op basis van de modellen van inhoudsfragmenten.
- Met behulp van uw schema's geeft GraphQL de typen en bewerkingen weer die zijn toegestaan voor de GraphQL voor AEM implementatie.
-
-
Het pad in AEM dat reageert op GraphQL-query's en toegang biedt tot de GraphQL-schema's.
-
Zie GraphQL Endpoint inschakelen voor nadere bijzonderheden.
-
Zie de (GraphQL.org) Inleiding tot GraphQL voor uitvoerige informatie, waaronder de Aanbevolen procedures.
GraphQL-querytypen graphql-query-types
Met GraphQL kunt u query's uitvoeren die worden geretourneerd:
-
A enkel item
AEM biedt mogelijkheden om query's (beide typen) om te zetten in Blijvende query's die door Dispatcher en CDN in het cachegeheugen worden opgeslagen.
Best practices voor GraphQL-query (Dispatcher en CDN) graphql-query-best-practices
Blijvende query's zijn de aanbevolen methode voor het publiceren van exemplaren als:
- ze zijn in cache geplaatst
- zij worden centraal beheerd door AEM
GraphQL-query's die gebruikmaken van POST-aanvragen worden niet aanbevolen omdat ze niet in de cache zijn opgeslagen, zodat in een standaardinstantie de Dispatcher is geconfigureerd om dergelijke query's te blokkeren.
Hoewel GraphQL ook GET-aanvragen ondersteunt, kunnen deze aanvragen limieten bereiken (bijvoorbeeld de lengte van de URL) die kunnen worden vermeden door middel van doorlopende query's.
Zie Het in cache plaatsen van doorlopende query's inschakelen voor nadere bijzonderheden.
GraphiQL Interface graphiql-interface
Tenuitvoerlegging van de norm GraphiQL kan worden gebruikt met AEM GraphQL.
Met deze interface kunt u query's rechtstreeks invoeren en testen.
Bijvoorbeeld:
http://localhost:4502/content/graphiql.html
De klasse biedt functies zoals syntaxismarkering, automatisch aanvullen en automatisch voorstellen, samen met een geschiedenis en online documentatie:
Kwesties gebruiken voor auteur- en publicatie-omgevingen use-cases-author-publish-environments
De gebruiksgevallen kunnen afhankelijk zijn van het type AEM omgeving:
-
Publicatie-omgeving; wordt gebruikt voor:
- Query-gegevens voor JS-toepassing (standaardgebruikscenario)
-
Auteursomgeving; gebruikt voor:
-
Query-gegevens voor "inhoudsbeheerdoeleinden":
- GraphQL in AEM is een alleen-lezen API.
- De REST-API kan worden gebruikt voor CR(u)D-bewerkingen.
-
Machtigingen permission
De machtigingen zijn vereist voor toegang tot middelen.
GraphQL query's worden uitgevoerd met toestemming van de AEM gebruiker van het onderliggende verzoek. Als de gebruiker geen leestoegang heeft tot bepaalde fragmenten (opgeslagen als elementen), maken deze geen deel uit van de resultatenset.
Ook, moet de gebruiker toegang tot een eindpunt van GraphQL hebben om de vragen van GraphQL in werking te kunnen stellen.
Schema genereren schema-generation
GraphQL is een getypeerde API, wat betekent dat de gegevens duidelijk gestructureerd en ingedeeld moeten zijn op basis van het type.
De GraphQL-specificatie biedt een aantal richtlijnen voor het maken van een robuuste API voor het ondervragen van gegevens over een bepaalde instantie. Om deze richtlijnen te voltooien, moet een cliënt halen Schema, die alle typen bevat die nodig zijn voor een query.
Voor inhoudsfragmenten zijn de GraphQL-schema's (structuur en typen) gebaseerd op Ingeschakeld Modellen van inhoudsfragmenten en hun gegevenstypen.
Als een gebruiker bijvoorbeeld een Content Fragment Model heeft gemaakt, genaamd Article
AEM vervolgens een GraphQL-type genereert ArticleModel
. De velden in dit type komen overeen met de velden en gegevenstypen die in het model zijn gedefinieerd. Bovendien leidt het tot sommige ingangspunten voor de vragen die op dit type werken, zoals articleByPath
of articleList
.
-
A Content Fragment Model:
-
Het corresponderende GraphQL-schema (uitvoer van de automatische documentatie GraphiQL):
Deze afbeelding laat zien dat het gegenereerde type
ArticleModel
bevat diverse velden.-
Drie van hen zijn gecontroleerd door de gebruiker:
author
,main
, enreferencearticle
. -
De andere velden zijn automatisch AEM toegevoegd en zijn nuttige methoden voor het verschaffen van informatie over een bepaald inhoudsfragment. In dit voorbeeld, helpervelden)
_path
,_metadata
,_variations
.
-
-
Nadat een gebruiker een inhoudsfragment heeft gemaakt op basis van het artikelmodel, kan het vervolgens worden ondervraagd via GraphQL. Zie voor voorbeelden de Voorbeeldquery's (op basis van een voorbeeldstructuur van inhoudsfragment voor gebruik met GraphQL).
In GraphQL for AEM is het schema flexibel. Deze flexibiliteit betekent dat deze automatisch wordt gegenereerd wanneer een inhoudsfragmentmodel wordt gemaakt, bijgewerkt of verwijderd. De caches voor het gegevensschema worden ook vernieuwd wanneer u een model van het inhoudsfragment bijwerkt.
De service Sites GraphQL luistert (op de achtergrond) naar eventuele wijzigingen die zijn aangebracht in een inhoudsfragmentmodel. Wanneer updates worden ontdekt, slechts wordt dat deel van het schema opnieuw geproduceerd. Deze optimalisatie bespaart tijd en zorgt voor stabiliteit.
Als u bijvoorbeeld:
-
Een pakket installeren met
Content-Fragment-Model-1
enContent-Fragment-Model-2
:- GraphQL-typen voor
Model-1
enModel-2
worden gegenereerd.
- GraphQL-typen voor
-
Vervolgens wijzigen
Content-Fragment-Model-2
:-
Alleen de
Model-2
GraphQL-type wordt bijgewerkt. -
Overwegende dat
Model-1
blijft hetzelfde.
-
Het schema wordt gediend door het zelfde eindpunt zoals de vragen van GraphQL, met de cliënt die het feit behandelt dat het schema met de uitbreiding wordt geroepen GQLschema
. U kunt bijvoorbeeld een eenvoudige GET
verzoek op /content/cq:graphql/global/endpoint.GQLschema
resulteert in de uitvoer van het schema met het inhoudstype: text/x-graphql-schema;charset=iso-8859-1
.
Schema genereren - Niet-gepubliceerde modellen schema-generation-unpublished-models
Wanneer Inhoudsfragmenten zijn genest, kan een bovenliggend inhoudsfragmentmodel worden gepubliceerd, maar een model waarnaar wordt verwezen, niet.
Wanneer dit gebeurt, genereert AEM een onvolledig Schema voor het bovenliggende inhoudsfragmentmodel. Dit betekent dat de fragmentverwijzing, die afhankelijk is van het niet-gepubliceerde model, uit het schema wordt verwijderd.
Velden fields
Binnen het schema zijn er afzonderlijke velden, van twee basiscategorieën:
-
Velden die u genereert.
Een selectie van Gegevenstypen worden gebruikt om velden te maken die zijn gebaseerd op de manier waarop u het inhoudsfragmentmodel configureert. De veldnamen zijn afkomstig uit het Eigenschapnaam van het Gegevenstype.
- Er is ook Renderen als het plaatsen om te overwegen, aangezien de gebruikers bepaalde gegevenstypes kunnen vormen. Een tekstveld met één regel kan bijvoorbeeld zo worden geconfigureerd dat het meerdere tekst met één regel bevat
multifield
in de vervolgkeuzelijst.
- Er is ook Renderen als het plaatsen om te overwegen, aangezien de gebruikers bepaalde gegevenstypes kunnen vormen. Een tekstveld met één regel kan bijvoorbeeld zo worden geconfigureerd dat het meerdere tekst met één regel bevat
-
GraphQL for AEM genereert ook een aantal helpervelden.
Deze velden worden gebruikt om een inhoudsfragment te identificeren of om meer informatie over een inhoudsfragment op te halen.
Gegevenstypen data-types
GraphQL for AEM ondersteunt een lijst met typen. Alle ondersteunde gegevenstypen van het inhoudsfragmentmodel en de bijbehorende GraphQL-typen worden weergegeven:
String
, [String]
String
Float
, [Float]
Boolean
Calendar
onlyDate
, onlyTime
, dateTime
String
[String]
String
Enkel veld:
Model
- Modeltype, rechtstreeks verwezenMeerdere velden, met één type waarnaar wordt verwezen:
[Model]
- Array van type Model
, rechtstreeks vanaf een arrayMeerdere velden, met meerdere typen waarnaar wordt verwezen:
[AllFragmentModels]
- Array van alle modeltypen, met verwijzing van array met type unionHelpervelden helper-fields
Naast de gegevenstypen voor door de gebruiker gegenereerde velden, genereert GraphQL for AEM ook verschillende helper velden voor het herkennen van een inhoudsfragment of voor aanvullende informatie over een inhoudsfragment.
Deze helpervelden zijn gemarkeerd met een voorgaande _
om onderscheid te maken tussen wat door de gebruiker is gedefinieerd en wat automatisch is gegenereerd.
Pad path
Het padveld wordt gebruikt als een identifier in AEM GraphQL. Het vertegenwoordigt het pad van het Content Fragment-element in de AEM opslagplaats. Dit pad wordt gekozen als de id van een inhoudsfragment, omdat het:
- uniek is binnen AEM,
- kan gemakkelijk worden opgehaald.
Met de volgende code worden de paden weergegeven van alle inhoudsfragmenten die zijn gemaakt op basis van het model van het inhoudsfragment Person
.
{
personList {
items {
_path
}
}
}
Als u één inhoudsfragment van een bepaald type wilt ophalen, moet u ook eerst het pad ervan bepalen. Bijvoorbeeld:
{
authorByPath(_path: "/content/dam/path/to/fragment/john-doe") {
item {
_path
firstName
name
}
}
}
Zie Voorbeeldquery - één specifiek stedenfragment.
Metagegevens metadata
Via GraphQL worden AEM ook de metagegevens van een inhoudsfragment beschikbaar gemaakt. Metagegevens zijn de informatie die een inhoudsfragment beschrijft, zoals het volgende:
- de titel van een inhoudsfragment
- het pad naar de miniatuur
- de beschrijving van een inhoudsfragment
- en de datum waarop het is gemaakt, onder andere.
Omdat metagegevens worden gegenereerd via de Schema-editor en als zodanig geen specifieke structuur hebben, TypedMetaData
Het GraphQL-type is geïmplementeerd om de metagegevens van een inhoudsfragment beschikbaar te maken. De TypedMetaData
stelt de informatie bloot die door de volgende scalaire types wordt gegroepeerd:
stringMetadata:[StringMetadata]!
stringArrayMetadata:[StringArrayMetadata]!
intMetadata:[IntMetadata]!
intArrayMetadata:[IntArrayMetadata]!
floatMetadata:[FloatMetadata]!
floatArrayMetadata:[FloatArrayMetadata]!
booleanMetadata:[BooleanMetadata]!
booleanArrayMetadata:[booleanArrayMetadata]!
calendarMetadata:[CalendarMetadata]!
calendarArrayMetadata:[CalendarArrayMetadata]!
Elk scalair type vertegenwoordigt of één enkel naam-waarde paar of een serie van naam-waarde paren, waar de waarde van dat paar van het type is het werd gegroepeerd.
Als u bijvoorbeeld de titel van een inhoudsfragment wilt ophalen, is deze eigenschap een eigenschap String, zodat u een query voor alle metagegevens van tekenreeks kunt uitvoeren:
Ga als volgt te werk om te zoeken naar metagegevens:
{
personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
item {
_path
_metadata {
stringMetadata {
name
value
}
}
}
}
}
U kunt alle GraphQL-typen voor metagegevens weergeven als u het schema Gegenereerde GraphQL weergeeft. Alle modeltypen hebben dezelfde TypedMetaData
.
Houd er rekening mee dat
StringMetadata
en StringArrayMetadata
beide verwijzen naar wat in de bewaarplaats wordt opgeslagen, niet hoe u hen terugwint.stringMetadata
veld, ontvangt u een array van alle metagegevens die in de repository zijn opgeslagen als een String
. En als je belt stringArrayMetadata
ontvangt u een array van alle metagegevens die in de opslagplaats zijn opgeslagen als String[]
.Zie Voorbeeldquery voor metagegevens - Lijst met metagegevens voor onderscheidingen: GB.
Variaties variations
De _variations
is geïmplementeerd om het opvragen van variaties in een inhoudsfragment te vereenvoudigen. Bijvoorbeeld:
{
personByPath(_path: "/content/dam/path/to/fragment/john-doe") {
item {
_variations
}
}
}
_variations
veld bevat geen master
variatie, als technisch gezien de oorspronkelijke gegevens (als Master in de gebruikersinterface) wordt niet als een expliciete wijziging beschouwd.Zie Voorbeeldquery - Alle steden met een benoemde variatie.
GraphQL-variabelen graphql-variables
GraphQL staat toe dat variabelen in de query worden geplaatst. Zie voor meer informatie GraphQL-documentatie voor variabelen.
Als u bijvoorbeeld alle inhoudsfragmenten van het type wilt ophalen Article
die een specifieke variatie hebben, kunt u de variabele opgeven variation
in GraphiQL.
### query
query GetArticlesByVariation($variation: String!) {
articleList(variation: $variation) {
items {
_path
author
_variations
}
}
}
### in query variables
{
"variation": "uk"
}
GraphQL-richtlijnen graphql-directives
In GraphQL is er een mogelijkheid om de query te wijzigen op basis van variabelen, de zogenaamde GraphQL-richtlijnen.
Hier kunt u bijvoorbeeld de opdracht adventurePrice
veld in een query voor alle AdventureModels
, gebaseerd op een variabele includePrice
.
### query
query GetAdventureByType($includePrice: Boolean!) {
adventureList {
items {
adventureTitle
adventurePrice @include(if: $includePrice)
}
}
}
### in query variables
{
"includePrice": true
}
Filteren filtering
U kunt filteren ook gebruiken in uw GraphQL-query's om specifieke gegevens te retourneren.
Bij het filteren wordt een syntaxis gebruikt die is gebaseerd op logische operatoren en expressies.
Het meest atomische deel bestaat uit één expressie die kan worden toegepast op de inhoud van een bepaald veld. De inhoud van het veld wordt vergeleken met een bepaalde constante waarde.
De volgende expressie zou bijvoorbeeld de inhoud van het veld vergelijken met de waarde some text
en slagen als de inhoud gelijk is aan de waarde. Anders mislukt de expressie:
{
value: "some text"
_op: EQUALS
}
De volgende operatoren kunnen worden gebruikt om velden met een bepaalde waarde te vergelijken:
EQUALS
String
, ID
, Boolean
EQUALS_NOT
String
, ID
CONTAINS
String
{ value: "mas", _op: CONTAINS }
overeenkomsten Christmas
, Xmas
, master
, …)CONTAINS_NOT
String
STARTS_WITH
ID
{ value: "/content/dam/", _op: STARTS_WITH
overeenkomsten /content/dam/path/to/fragment
, maar niet /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
Bij sommige typen kunt u ook aanvullende opties opgeven die wijzigen hoe een expressie wordt geëvalueerd:
_ignoreCase
String
time
overeenkomsten TIME
, time
, tImE
, …_sensitiveness
Float
float
als hetzelfde te beschouwen waarden (om technische beperkingen te omzeilen als gevolg van de interne representatie van float
waarden; moet worden vermeden, aangezien deze optie een negatief effect kan hebben op de prestatiesExpressies kunnen met behulp van een logische operator worden gecombineerd tot een set (_logOp
):
OR
- de reeks expressies slaagt als ten minste één expressie slaagtAND
- de reeks expressies slaagt als alle expressies slagen (standaardwaarde)
Elk veld kan met een eigen set expressies worden gefilterd. De expressiesets van alle velden die in het filterargument worden vermeld, worden uiteindelijk gecombineerd door de eigen logische operator.
Een filterdefinitie (doorgegeven als de filter
argument voor een query) bevat:
- Een subdefinitie voor elk gebied (het gebied kan door zijn naam worden betreden, bijvoorbeeld, is er een
lastName
veld in het filter voor delastName
veld in het gegevenstype (veld) - Elke subdefinitie bevat de
_expressions
array, die de expressieset en de_logOp
veld waarin de logische operator wordt gedefinieerd, moeten de expressies worden gecombineerd met - Elke expressie wordt gedefinieerd door de waarde (
value
veld) en de operator (_operator
veld) de inhoud van een veld moet worden vergeleken met
U kunt weglaten _logOp
als je objecten wilt combineren met AND
en _operator
als u op gelijkheid wilt controleren, omdat deze waarden standaardwaarden zijn.
Het volgende voorbeeld toont een volledige vraag aan die alle personen filtert die een lastName
van Provo
of die sjö
onafhankelijk van de zaak:
{
authorList(filter: {
lastname: {
_logOp: OR
_expressions: [
{
value: "sjö",
_operator: CONTAINS,
_ignoreCase: true
},
{
value: "Provo"
}
]
}
}) {
items {
lastName
firstName
}
}
}
Wanneer u een GraphQL-query uitvoert met behulp van optionele variabelen, als een specifieke waarde niet gegeven voor de facultatieve variabele, dan zal de variabele in de filterevaluatie worden genegeerd. Dit betekent dat zoekresultaten alle waarden bevatten, beide null
en niet null
, voor de eigenschap met betrekking tot de filtervariabele.
null
waarde is expliciet opgegeven voor een dergelijke variabele, komt het filter alleen overeen null
waarden voor de bijbehorende eigenschap.In de query hieronder ziet u bijvoorbeeld waar geen waarde is opgegeven voor de eigenschap lastName
:
query getAuthorsFilteredByLastName($authorLastName: String) {
authorList(filter:
{
lastName: {_expressions: {value: $authorLastName}
}}) {
items {
lastName
}
}
}
Alle auteurs worden geretourneerd:
{
"data": {
"authorList": {
"items": [
{
"lastName": "Hammer"
},
{
"lastName": "Provo"
},
{
"lastName": "Wester"
},
{
"lastName": null
},
...
]
}
}
}
U kunt ook filteren op geneste velden, maar dit wordt afgeraden omdat dit tot prestatieproblemen kan leiden.
Zie voor meer voorbeelden:
-
nadere gegevens over de GraphQL for AEM extensions
-
Voorbeeldquery's met deze voorbeeldinhoud en -structuur
- En de Voorbeeldinhoud en -structuur voorbereid voor gebruik in voorbeeldquery's
Sorteren sorting
Met deze functie kunt u de zoekresultaten sorteren op basis van een opgegeven veld.
De sorteercriteria:
-
is een door komma's gescheiden lijst met waarden die het veldpad aangeven
-
het eerste veld in de lijst definieert de primaire sorteervolgorde
- het tweede veld wordt gebruikt als twee waarden van het primaire sorteercriterium gelijk zijn
- het derde veld wordt gebruikt als de eerste twee criteria gelijk zijn , enzovoort .
-
puntnotatie, dat wil zeggen:
field1.subfield.subfield
, enzovoort.
-
-
met een optionele bestelrichting
- ASC (oplopend) of DESC (aflopend); als standaard ASC wordt toegepast
- de richting kan per gebied worden gespecificeerd; dit vermogen betekent dat u één gebied in stijgende orde kunt sorteren, een andere in dalende orde (naam, firstName DESC)
Bijvoorbeeld:
query {
authorList(sort: "lastName, firstName") {
items {
firstName
lastName
}
}
}
En ook:
{
authorList(sort: "lastName DESC, firstName DESC") {
items {
lastName
firstName
}
}
}
U kunt ook sorteren op een veld in een genest fragment in de notatie nestedFragmentname.fieldname
.
Bijvoorbeeld:
query {
articleList(sort: "authorFragment.lastName") {
items {
title
authorFragment {
firstName
lastName
birthDay
}
slug
}
}
}
Paginering paging
Met deze functie kunt u pagineren uitvoeren op querytypen die een lijst retourneren. Er zijn twee methoden:
offset
enlimit
in eenList
queryfirst
enafter
in eenPaginated
query
Lijstquery - Verschuiven en beperken list-offset-limit
In een ...List
query die u kunt gebruiken offset
en limit
om een specifieke subset van resultaten te retourneren:
offset
: Geeft de eerste gegevensset aan die moet worden geretourneerdlimit
: Geeft het maximale aantal gegevenssets op dat moet worden geretourneerd
Als u bijvoorbeeld de resultatenpagina wilt weergeven met maximaal vijf artikelen, te beginnen bij het vijfde artikel van het dialoogvenster complete resultatenlijst:
query {
articleList(offset: 5, limit: 5) {
items {
authorFragment {
lastName
firstName
}
}
}
}
-
De paginering vereist een stabiele soortorde om correct over veelvoudige vragen te werken die verschillende pagina's van de zelfde resultaatreeks vragen. Standaard wordt het pad naar de opslagplaats van elk item van de resultaatset gebruikt om ervoor te zorgen dat de volgorde altijd gelijk is. Als een verschillende sorteervolgorde wordt gebruikt en als die sortering niet kan worden uitgevoerd op JCR-queryniveau, heeft dat een negatief effect op de prestaties. De reden hiervoor is dat de volledige resultaatset in het geheugen moet worden geladen voordat de pagina's worden bepaald.
-
Hoe hoger de verschuiving, des te meer tijd neemt het om de items van de volledige set JCR-queryresultaten over te slaan. Een alternatieve oplossing voor grote resultaatreeksen is de gepagineerde vraag met te gebruiken
first
enafter
methode.
Gepagineerde query - eerste en volgende paginated-first-after
De ...Paginated
het vraagtype gebruikt het grootste deel van ...List
functies voor querytypen (filteren, sorteren), maar in plaats van offset
/limit
argumenten, gebruikt het de first
/after
argumenten zoals gedefinieerd door de GraphQL Cursor Connections Specification. U vindt een minder formele introductie in het dialoogvenster Inleiding GraphQL.
first
: Den
eerste objecten die moeten worden geretourneerd.
De standaardwaarde is50
.
Het maximum is100
.after
: De cursor die het begin van de opgevraagde pagina bepaalt. Het punt dat door de curseur wordt vertegenwoordigd is niet inbegrepen in de resultaatreeks. De cursor van een item wordt bepaald door decursor
van hetedges
structuur.
Voer bijvoorbeeld de resultatenpagina uit met maximaal vijf avonturen, te beginnen bij het opgegeven cursoritem in het dialoogvenster complete resultatenlijst:
query {
adventurePaginated(first: 5, after: "ODg1MmMyMmEtZTAzMy00MTNjLThiMzMtZGQyMzY5ZTNjN2M1") {
edges {
cursor
node {
title
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
-
Standaard wordt bij paginering de UUID gebruikt van het opslagplaats-knooppunt dat het fragment vertegenwoordigt voor de volgorde van de resultaten, om ervoor te zorgen dat de volgorde van de resultaten altijd gelijk is. Wanneer
sort
wordt gebruikt, wordt UUID impliciet gebruikt om een unieke soort te verzekeren; zelfs voor twee punten met identieke soortsleutels. -
Als gevolg van interne technische beperkingen neemt de prestatie af als sortering en filtering worden toegepast op geneste velden. Gebruik daarom filter-/sorteervelden die op hoofdniveau zijn opgeslagen. Deze techniek is ook de geadviseerde manier als u grote gepagineerde resultaatreeksen wilt vragen.
GraphQL Persisted Queries - caching inschakelen in Dispatcher graphql-persisted-queries-enabling-caching-dispatcher
Caching van persisted query's wordt niet standaard ingeschakeld in de Dispatcher. De standaard enablement is niet mogelijk aangezien de klanten die CORS (het Delen van het Middel van de Cross-Origin) met veelvoudige oorsprong gebruiken hun configuratie van de Verzender moeten herzien en misschien bijwerken.
Vary
header.Het in cache plaatsen van doorlopende query's inschakelen enable-caching-persisted-queries
Om het in cache plaatsen van persisted query's in te schakelen, zijn de volgende updates van de Dispatcher-configuratiebestanden vereist:
-
<conf.d/rewrites/base_rewrite.rules>
code language-xml # Allow the dispatcher to be able to cache persisted queries - they need an extension for the cache file RewriteCond %{REQUEST_URI} ^/graphql/execute.json RewriteRule ^/(.*)$ /$1;.json [PT]
note note NOTE Dispatcher voegt het achtervoegsel toe .json
aan alle persisted query-URL's, zodat het resultaat in de cache kan worden opgeslagen.Zo zorgt u ervoor dat de query voldoet aan de vereisten van de Dispatcher voor documenten die in cache kunnen worden geplaatst. Zie voor meer informatie Hoe retourneert de Dispatcher documenten? -
<conf.dispatcher.d/filters/ams_publish_filters.any>
code language-xml # Allow GraphQL Persisted Queries & preflight requests /0110 { /type "allow" /method '(GET|POST|OPTIONS)' /url "/graphql/execute.json*" }
CORS-configuratie in de Dispatcher cors-configuration-in-dispatcher
Klanten die CORS-verzoeken gebruiken, moeten mogelijk hun CORS-configuratie in de Dispatcher controleren en bijwerken.
-
De
Origin
header mag niet worden doorgegeven aan AEM publish via Dispatcher:- Controleer de
clientheaders.any
bestand.
- Controleer de
-
In plaats daarvan, moeten de verzoeken CORS voor toegestane oorsprong op het niveau van de Verzender worden geëvalueerd. Deze benadering zorgt er ook voor dat aan CORS gerelateerde koppen in alle gevallen correct worden ingesteld op één plaats.
- Een dergelijke configuratie moet worden toegevoegd aan de
vhost
bestand. Hieronder wordt een voorbeeldconfiguratie gegeven; voor de eenvoud is alleen het gedeelte met betrekking tot CORS opgenomen. U kunt deze aanpassen voor uw specifieke gebruiksgevallen.
code language-xml <VirtualHost *:80> ServerName "publish" # ... <IfModule mod_headers.c> Header add X-Vhost "publish" ################## Start of the CORS specific configuration ################## SetEnvIfExpr "req_novary('Origin') == ''" CORSType=none CORSProcessing=false SetEnvIfExpr "req_novary('Origin') != ''" CORSType=cors CORSProcessing=true CORSTrusted=false SetEnvIfExpr "req_novary('Access-Control-Request-Method') == '' && %{REQUEST_METHOD} == 'OPTIONS' && req_novary('Origin') != '' " CORSType=invalidpreflight CORSProcessing=false SetEnvIfExpr "req_novary('Access-Control-Request-Method') != '' && %{REQUEST_METHOD} == 'OPTIONS' && req_novary('Origin') != '' " CORSType=preflight CORSProcessing=true CORSTrusted=false SetEnvIfExpr "req_novary('Origin') -strcmatch 'https://%{HTTP_HOST}*'" CORSType=samedomain CORSProcessing=false # For requests that require CORS processing, check if the Origin can be trusted SetEnvIfExpr "%{HTTP_HOST} =~ /(.*)/ " ParsedHost=$1 ################## Adapt the regex to match CORS origin for your environment SetEnvIfExpr "env('CORSProcessing') == 'true' && req_novary('Origin') =~ m#(https://.*.your-domain.tld(:\d+)?$)#" CORSTrusted=true # Extract the Origin header SetEnvIfNoCase ^Origin$ ^https://(.*)$ CORSTrustedOrigin=https://$1 # Flush If already set Header unset Access-Control-Allow-Origin Header unset Access-Control-Allow-Credentials # Trusted Header always set Access-Control-Allow-Credentials "true" "expr=reqenv('CORSTrusted') == 'true'" Header always set Access-Control-Allow-Origin "%{CORSTrustedOrigin}e" "expr=reqenv('CORSTrusted') == 'true'" Header always set Access-Control-Allow-Methods "GET" "expr=reqenv('CORSTrusted') == 'true'" Header always set Access-Control-Max-Age 1800 "expr=reqenv('CORSTrusted') == 'true'" Header always set Access-Control-Allow-Headers "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers" "expr=reqenv('CORSTrusted') == 'true'" # Non-CORS or Not Trusted Header unset Access-Control-Allow-Credentials "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'" Header unset Access-Control-Allow-Origin "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'" Header unset Access-Control-Allow-Methods "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'" Header unset Access-Control-Max-Age "expr=reqenv('CORSProcessing') == 'false' || reqenv('CORSTrusted') == 'false'" # Always vary on origin, even if its not there. Header merge Vary Origin # CORS - send 204 for CORS requests which are not trusted RewriteCond expr "reqenv('CORSProcessing') == 'true' && reqenv('CORSTrusted') == 'false'" RewriteRule "^(.*)" - [R=204,L] ################## End of the CORS specific configuration ################## </IfModule> <Directory /> # ... </Directory> # ... </VirtualHost>
- Een dergelijke configuratie moet worden toegevoegd aan de
GraphQL for AEM - Overzicht van extensies graphql-extensions
De basisverrichting van vragen met GraphQL voor AEM voldoet aan de standaardspecificatie van GraphQL. Voor GraphQL-query's met AEM zijn er een aantal extensies:
-
Als u één resultaat nodig hebt:
- gebruik de modelnaam; bijvoorbeeld stad
-
Als u een lijst met resultaten verwacht:
- toevoegen
List
op de modelnaam, bijvoorbeeldcityList
- Zie Voorbeeldquery - Alle informatie over alle steden
U kunt dan:
-
ASC
: oplopendDESC
: aflopend
-
Retourneer een pagina met resultaten met:
- toevoegen
-
Het filter
includeVariations
is opgenomen in deList
querytype. Als u Variaties in inhoudsfragmenten wilt ophalen in de queryresultaten, kunt u de opdrachtincludeVariations
filter moet worden ingesteld optrue
.note caution CAUTION Het filter includeVariations
kan niet samen met het door het systeem gegenereerde veld worden gebruikt_variation
. -
Als u logische OR wilt gebruiken:
- gebruiken
_logOp: OR
- Zie Voorbeeldquery - Alle personen met de naam "Jobs" of "Smith"
- gebruiken
-
Logische AND bestaat ook, maar is (vaak) impliciet
-
U kunt zoeken naar veldnamen die overeenkomen met de velden in het model van het inhoudsfragment
-
Naast de velden van uw model zijn er velden die door het systeem worden gegenereerd (voorafgegaan door een onderstrepingsteken):
-
Voor inhoud:
-
_locale
: om de taal te onthullen; gebaseerd op Taalbeheer -
_metadata
: om metagegevens voor het fragment weer te geven -
_model
: Vragen naar een inhoudsfragmentmodel toestaan (pad en titel) -
_path
: het pad naar het inhoudsfragment in de opslagplaats -
_reference
: om verwijzingen weer te geven; inline-verwijzingen opnemen in de Rich Text Editor -
_variation
: om specifieke variaties in het inhoudsfragment weer te gevennote note NOTE Als de opgegeven variatie niet bestaat voor een inhoudsfragment, wordt de hoofdvariatie geretourneerd als een standaardinstelling (fallback). note caution CAUTION Het systeemgegenereerde veld _variation
kan niet samen met het filter worden gebruiktincludeVariations
. -
_tags
: om de id's weer te geven van inhoudsfragmenten of variaties die tags bevatten; deze lijst is een array vancq:tags
id's.- Zie Voorbeeldquery - Namen van alle steden die zijn getagd als stadseinden
- Zie Voorbeeldquery voor variaties van inhoudsfragmenten van een bepaald model waaraan een specifieke tag is gekoppeld
note note NOTE Tags kunnen ook worden opgevraagd door de metagegevens van een inhoudsfragment weer te geven.
-
-
En bewerkingen:
-
_operator
: specifieke exploitanten toepassen;EQUALS
,EQUALS_NOT
,GREATER_EQUAL
,LOWER
,CONTAINS
,STARTS_WITH
-
_apply
: specifieke voorwaarden toepassen, bijvoorbeeldAT_LEAST_ONCE
-
_ignoreCase
: om de zaak te negeren bij het vragen
-
-
-
GraphQL-union-typen worden ondersteund:
-
Extra fallback bij het opvragen van geneste fragmenten:
- Als de gevraagde variatie niet bestaat in een genest fragment, wordt de Master variation is returned.
CORS-filter cors-filter
Om tot het eindpunt van GraphQL toegang te hebben, vorm een beleid CORS in de bewaarplaats van de Kit van de klant. Deze configuratie wordt gedaan door een aangewezen OSGi CORS configuratiedossier voor één of meerdere gewenste eindpunten toe te voegen.
Deze configuratie moet een vertrouwde website-oorsprong opgeven alloworigin
of alloworiginregexp
waarvoor toegang moet worden verleend.
Bijvoorbeeld, om toegang tot het eindpunt van GraphQL en voortgeduurde vragen te verlenen eindpunt voor https://my.domain
u kunt gebruiken:
{
"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/.*"
]
}
Als u een ijdelingspad voor het eindpunt hebt gevormd, kunt u het binnen ook gebruiken allowedpaths
.
Refererfilter referrer-filter
Naast de configuratie CORS, moet een filter van de Referateur worden gevormd om toegang van derdegastheren toe te staan.
Dit filter wordt gedaan door een aangewezen OSGi de configuratiedossier van de Filter toe te voegen dat:
- geeft een hostnaam voor een vertrouwde website op; ofwel
allow.hosts
ofallow.hosts.regexp
, - verleent toegang voor deze gastheernaam.
Bijvoorbeeld om toegang voor verzoeken met de Referiteur te verlenen my.domain
u kunt:
{
"allow.empty":false,
"allow.hosts":[
"my.domain"
],
"allow.hosts.regexp":[
""
],
"filter.methods":[
"POST",
"PUT",
"DELETE",
"COPY",
"MOVE"
],
"exclude.agents.regexp":[
""
]
}
- alleen toegang verlenen tot vertrouwde domeinen
- ervoor zorgen dat geen gevoelige informatie wordt blootgesteld
- geen jokerteken gebruiken [*] syntaxis; deze functionaliteit maakt voor authentiek verklaarde toegang tot het eindpunt van GraphQL onbruikbaar en stelt het ook aan de volledige wereld bloot.
Beperkingen limitations
Om tegen potentiële problemen te beschermen worden er standaardbeperkingen opgelegd aan uw vragen:
- De query mag niet meer dan 1M (1024 * 1024) tekens bevatten
- De query mag niet meer dan 15000 tokens bevatten
- De query mag niet meer dan 200000 whitespace-tokens bevatten
U moet zich ook bewust zijn van:
-
Er wordt een fout in een veldconflict geretourneerd wanneer uw GraphQL-query velden met dezelfde naam bevat in twee (of meer) modellen en aan de volgende voorwaarden wordt voldaan:
-
Dus waar:
- Twee (of meer modellen) worden gebruikt als mogelijke verwijzingen; wanneer zij als toegestaan worden gedefinieerd Modeltype in de Content Fragment reference.
en:
- Deze twee modellen hebben gebieden met een gemeenschappelijke naam; dat betekent de zelfde naam voorkomt in beide modellen.
en
- Deze velden zijn van verschillende gegevenstypen.
-
Bijvoorbeeld:
-
Wanneer twee (of meer) fragmenten met verschillende modellen (bijvoorbeeld
M1
,M2
) worden gebruikt als mogelijke verwijzingen (Content Reference of Fragment Reference) uit een ander fragment, bijvoorbeeldFragment1
MultiField/List
-
Deze twee fragmenten met verschillende modellen (
M1
,M2
) hebben velden met dezelfde naam, maar verschillende typen.
Ter illustratie:M1.Title
alsText
M2.Title
alsText/MultiField
-
Dan zal een fout van het gebiedsconflict voorkomen als de vraag van GraphQL bevat
Title
veld.
-
-
Verificatie authentication
Zie Verificatie voor externe AEM GraphQL-query's op inhoudsfragmenten.
Veelgestelde vragen faqs
De gerezen vragen:
-
Q: "Hoe verschilt de GraphQL API voor AEM van de Query Builder-API?"
- A: "De AEM GraphQL API biedt volledige controle op de JSON-uitvoer en is een industriestandaard voor het opvragen van inhoud.
In de toekomst is AEM van plan te investeren in de AEM GraphQL API."
- A: "De AEM GraphQL API biedt volledige controle op de JSON-uitvoer en is een industriestandaard voor het opvragen van inhoud.
Zelfstudie - Aan de slag met AEM Headless en GraphQL tutorial
Op zoek naar een praktische zelfstudie? Uitchecken Aan de slag met AEM Headless en GraphQL end-to-end zelfstudie waarin wordt geïllustreerd hoe u in een CMS-scenario inhoud kunt ontwikkelen en beschikbaar maken met behulp van AEM GraphQL API's en die door een externe toepassing wordt verbruikt.