Les 5: Inhoud aanpassen voor verschillende gebruikers
We kunnen een andere respons ophalen in een veld afhankelijk van bepaalde gegevens in de query, zoals de rollen van de ingelogde gebruiker.
GraphQL-query om inhoud aan te passen voor verschillende gebruikers
Deze GraphQL-query haalt de berichtinhoud op en voegt een link "Bewerk dit bericht" toe onderaan de inhoud, maar alleen voor de beheerder:
query InitializeDynamicVariables
@configureWarningsOnExportingDuplicateVariable(enabled: false)
{
isAdminUser: _echo(value: false)
@export(as: "isAdminUser")
@remove
}
query ExportConditionalVariables
@depends(on: "InitializeDynamicVariables")
{
me {
roleNames @remove
isAdminUser: _inArray(
value: "administrator",
array: $__roleNames
)
@export(as: "isAdminUser")
}
}
query RetrieveContentForAdminUser($postId: ID!)
@depends(on: "ExportConditionalVariables")
@include(if: $isAdminUser)
{
post(by: { id : $postId }) {
originalContent: content @remove
wpAdminEditURL @remove
content: _sprintf(
string: "%s<p><a href=\"%s\">%s</a></p>",
values: [
$__originalContent,
$__wpAdminEditURL,
"(Admin only) Edit post"
]
)
}
}
query RetrieveContentForNonAdminUser($postId: ID!)
@depends(on: "ExportConditionalVariables")
@skip(if: $isAdminUser)
{
post(by: { id : $postId }) {
content
}
}
query ExecuteAll
@depends(on: [
"RetrieveContentForAdminUser",
"RetrieveContentForNonAdminUser"
])
{
id @remove
}Voor beheerders zal de respons er als volgt uitzien:
{
"data": {
"user": {
"isAdminUser": true
},
"post": {
"content": "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!<\/p>\n<p><a href=\"https:\/\/mysite.com\/wp-admin\/post.php?post=1&action=edit\">(Admin only) Edit post<\/a><\/p>"
}
}
}Voor niet-beheerders zal de respons er als volgt uitzien:
{
"data": {
"user": {
"isAdminUser": false
},
"post": {
"content": "\n<p>Welcome to WordPress. This is your first post. Edit or delete it, then start writing!<\/p>\n"
}
}
}De GraphQL-server laten (rekening houdend met alle mogelijke condities) de vereiste waarde voor een veld dynamisch berekenen:
- Vereenvoudigt de logica van de applicatie, omdat er één bron van waarheid is, de code DRY wordt en clients de bijbehorende logica niet meer zelf hoeven te implementeren
- Maakt de applicatie betrouwbaarder, met name wanneer meerdere clients gegevens van de server opvragen, omdat verschillende implementaties van dezelfde logica niet identiek kunnen zijn, wat mogelijk tot bugs leidt (des te meer wanneer clients op verschillende technologieën zijn gebaseerd, zoals JavaScript voor een website, Java voor een Android-app, Swift voor een iPhone-app, en andere)
Stap voor stap: de GraphQL-query opbouwen
Hieronder volgt een gedetailleerde analyse van hoe de query werkt.
Controleren of de gebruiker een beheerder is
Deze query controleert of de ingelogde gebruiker de rol "administrator" heeft, en exporteert deze conditie naar de dynamische variabele $isAdminUser:
query
{
me {
roleNames
isAdminUser: _inArray(
value: "administrator",
array: $__roleNames
)
@export(as: "isAdminUser")
}
}Conditionele uitvoering van operaties
Wanneer Meervoudige Query-uitvoering is ingeschakeld, kunnen de directives @include en @skip ook worden toegepast op operaties. Op die manier kunnen we een operatie al dan niet uitvoeren afhankelijk van de waarde van een dynamische variabele.
In de onderstaande query wordt slechts één van de twee operaties uitgevoerd:
RetrieveContentForAdminUserwordt alleen uitgevoerd wanneer$isAdminUsertrueisRetrieveContentForNonAdminUserwordt alleen uitgevoerd wanneer$isAdminUserfalseis
query RetrieveContentForAdminUser
@depends(on: "ExportConditionalVariables")
@include(if: $isAdminUser)
{
# ...
}
query RetrieveContentForNonAdminUser
@depends(on: "ExportConditionalVariables")
@skip(if: $isAdminUser)
{
# ...
}Laten we twee verschillende responsen geven voor het veld content van het bericht, afhankelijk van of de gebruiker een beheerder is of niet:
- De eerste operatie gebruikt
contentals alias en berekent de waarde van het veld dynamisch door de veldenoriginalContentenwpAdminEditURLsamen te voegen via_sprintf - De tweede operatie haalt het veld
contentrechtstreeks op
query RetrieveContentForAdminUser($postId: ID!)
@depends(on: "ExportConditionalVariables")
@include(if: $isAdminUser)
{
post(by: { id : $postId }) {
originalContent: content
wpAdminEditURL
content: _sprintf(
string: "%s<p><a href=\"%s\">%s</a></p>",
values: [
$__originalContent,
$__wpAdminEditURL,
"(Admin only) Edit post"
]
)
}
}
query RetrieveContentForNonAdminUser($postId: ID!)
@depends(on: "ExportConditionalVariables")
@skip(if: $isAdminUser)
{
post(by: { id : $postId }) {
content
}
}De uit te voeren operatie toevoegen
We hebben nu twee operaties die mogelijk worden uitgevoerd, maar we kunnen slechts één ?operationName=... opgeven bij het uitvoeren van de query.
Daarom voegen we de operatie ExecuteAll toe die afhankelijk is van zowel RetrieveContentForAdminUser als RetrieveContentForNonAdminUser, en die het eenvoudige veld id bevat (omdat we iets moeten opvragen in de operatie):
query ExecuteAll
@depends(on: [
"RetrieveContentForAdminUser",
"RetrieveContentForNonAdminUser"
])
{
id
}Door het eindpunt aan te roepen met ?operationName=ExecuteAll worden beide operaties geladen, maar slechts één ervan wordt daadwerkelijk uitgevoerd.
Overbodige gegevens verwijderen
De laatste stap is het verwijderen van alle hulpvelden (waarvan we de uitvoer niet in de respons nodig hebben) via @remove.
De geconsolideerde GraphQL-query is:
query InitializeDynamicVariables
@configureWarningsOnExportingDuplicateVariable(enabled: false)
{
isAdminUser: _echo(value: false)
@export(as: "isAdminUser")
@remove
}
query ExportConditionalVariables
@depends(on: "InitializeDynamicVariables")
{
me {
roleNames @remove
isAdminUser: _inArray(
value: "administrator",
array: $__roleNames
)
@export(as: "isAdminUser")
}
}
query RetrieveContentForAdminUser($postId: ID!)
@depends(on: "ExportConditionalVariables")
@include(if: $isAdminUser)
{
post(by: { id : $postId }) {
originalContent: content @remove
wpAdminEditURL @remove
content: _sprintf(
string: "%s<p><a href=\"%s\">%s</a></p>",
values: [
$__originalContent,
$__wpAdminEditURL,
"(Admin only) Edit post"
]
)
}
}
query RetrieveContentForNonAdminUser($postId: ID!)
@depends(on: "ExportConditionalVariables")
@skip(if: $isAdminUser)
{
post(by: { id : $postId }) {
content
}
}
query ExecuteAll
@depends(on: [
"RetrieveContentForAdminUser",
"RetrieveContentForNonAdminUser"
])
{
id @remove
}