Lektion 5: Inhalte für verschiedene Benutzer anpassen
Wir können eine unterschiedliche Antwort in einem Feld basierend auf abgefragten Daten abrufen, wie z. B. den Rollen des angemeldeten Benutzers.
GraphQL-Query zum Anpassen von Inhalten für verschiedene Benutzer
Diese GraphQL-Query ruft den Beitragsinhalt ab und fügt am Ende des Inhalts einen Link „Diesen Beitrag bearbeiten" nur für den Admin-Benutzer hinzu:
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
}Für Admin-Benutzer lautet die Antwort:
{
"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>"
}
}
}Für Nicht-Admin-Benutzer lautet die Antwort:
{
"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"
}
}
}Wenn der GraphQL-Server (angesichts aller möglichen Bedingungen) den erforderlichen Wert für ein Feld dynamisch berechnet:
- Vereinfacht dies die Logik der Anwendung, da es eine einzige Quelle der Wahrheit gibt, der Code wird DRY und Clients müssen die entsprechende Logik nicht mehr selbst implementieren
- Macht dies die Anwendung zuverlässiger, besonders wenn mehrere Clients auf Daten vom Server zugreifen, da unterschiedliche Implementierungen derselben Logik nicht identisch sein können und potenziell zu Bugs führen (umso mehr, wenn Clients auf unterschiedlichen Technologien basieren, wie JavaScript für eine Website, Java für eine Android-App, Swift für eine iPhone-App und andere)
Schritt für Schritt: die GraphQL-Query erstellen
Im Folgenden wird detailliert erläutert, wie die Query funktioniert.
Herausfinden, ob der Benutzer ein Admin ist
Diese Query prüft, ob der angemeldete Benutzer die Rolle "administrator" hat, und exportiert diese Bedingung in die dynamische Variable $isAdminUser:
query
{
me {
roleNames
isAdminUser: _inArray(
value: "administrator",
array: $__roleNames
)
@export(as: "isAdminUser")
}
}Bedingte Ausführung von Operationen
Wenn Multiple Query Execution aktiviert ist, können die Direktiven @include und @skip auch auf Operationen angewendet werden. Auf diese Weise können wir eine Operation je nach dem Wert einer dynamischen Variable ausführen oder nicht.
In der folgenden Query wird nur eine der beiden Operationen ausgeführt:
RetrieveContentForAdminUserwird nur ausgeführt, wenn$isAdminUsertrueistRetrieveContentForNonAdminUserwird nur ausgeführt, wenn$isAdminUserfalseist
query RetrieveContentForAdminUser
@depends(on: "ExportConditionalVariables")
@include(if: $isAdminUser)
{
# ...
}
query RetrieveContentForNonAdminUser
@depends(on: "ExportConditionalVariables")
@skip(if: $isAdminUser)
{
# ...
}Wir geben zwei verschiedene Antworten für das content-Feld des Beitrags zurück, je nachdem ob der Benutzer ein Admin ist oder nicht:
- Die erste Operation verwendet
contentals Alias und berechnet den Feldwert dynamisch, indem die FelderoriginalContentundwpAdminEditURLüber_sprintfzusammengeführt werden - Die zweite Operation ruft das
content-Feld direkt ab
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
}
}Die auszuführende Operation hinzufügen
Nun haben wir zwei Operationen, die ausgeführt werden können, aber wir können beim Ausführen der Query nur ein ?operationName=... angeben.
Daher fügen wir die Operation ExecuteAll hinzu, die sowohl von RetrieveContentForAdminUser als auch von RetrieveContentForNonAdminUser abhängt und das einfache Feld id enthält (weil wir in der Operation etwas abfragen müssen):
query ExecuteAll
@depends(on: [
"RetrieveContentForAdminUser",
"RetrieveContentForNonAdminUser"
])
{
id
}Der Aufruf des Endpunkts mit ?operationName=ExecuteAll lädt nun beide Operationen, aber nur eine davon wird tatsächlich ausgeführt.
Nicht benötigte Daten entfernen
Der letzte Schritt besteht darin, alle Felder, die Hilfszwecken dienen (und deren Ausgabe wir daher nicht in der Antwort benötigen), über @remove zu entfernen.
Die konsolidierte GraphQL-Query lautet:
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
}