Lezione 5: Personalizzare il contenuto per diversi utenti
Possiamo recuperare una risposta diversa in un campo in base a un dato interrogato, come i ruoli dell'utente connesso.
Query GraphQL per personalizzare il contenuto per diversi utenti
Questa query GraphQL recupera il contenuto di un articolo e aggiunge un link "Modifica questo articolo" in fondo al contenuto solo per l'utente amministratore:
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
}Per gli utenti amministratori, la risposta sarà :
{
"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>"
}
}
}Per gli utenti non amministratori, la risposta sarà :
{
"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"
}
}
}Lasciare che il server GraphQL (considerando tutte le possibili condizioni) calcoli dinamicamente il valore richiesto per un campo:
- Semplifica la logica dell'applicazione, poiché esiste un'unica fonte di verità , il codice diventa DRY e i client non devono più implementare la logica corrispondente
- Rende l'applicazione più affidabile, specialmente quando più client accedono ai dati dal server, poiché implementazioni diverse della stessa logica possono non essere identiche, portando potenzialmente a bug (ancor più quando i client si basano su tecnologie diverse, come JavaScript per un sito web, Java per un'app Android, Swift per un'app iPhone e altri)
Passo dopo passo: creazione della query GraphQL
Di seguito è riportata l'analisi dettagliata del funzionamento della query.
Verificare se l'utente è un amministratore
Questa query verifica se l'utente connesso ha il ruolo "administrator" ed esporta questa condizione nella variabile dinamica $isAdminUser:
query
{
me {
roleNames
isAdminUser: _inArray(
value: "administrator",
array: $__roleNames
)
@export(as: "isAdminUser")
}
}Esecuzione condizionale delle operazioni
Quando l'Esecuzione di multiple query è abilitata, le direttive @include e @skip possono essere applicate anche alle operazioni. In questo modo, possiamo eseguire o meno un'operazione in base al valore di una variabile dinamica.
Nella query seguente, solo una delle due operazioni verrà eseguita:
RetrieveContentForAdminUserviene eseguita solo quando$isAdminUserètrueRetrieveContentForNonAdminUserviene eseguita solo quando$isAdminUserèfalse
query RetrieveContentForAdminUser
@depends(on: "ExportConditionalVariables")
@include(if: $isAdminUser)
{
# ...
}
query RetrieveContentForNonAdminUser
@depends(on: "ExportConditionalVariables")
@skip(if: $isAdminUser)
{
# ...
}Forniamo due risposte diverse per il campo content dell'articolo in base al fatto che l'utente sia amministratore o meno:
- La prima operazione usa
contentcome alias e calcola il valore del campo dinamicamente, combinando i campioriginalContentewpAdminEditURLtramite_sprintf - La seconda operazione recupera il campo
contentdirettamente
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
}
}Aggiungere l'operazione da eseguire
Ora abbiamo due operazioni che possono essere eseguite, tuttavia possiamo fornire un solo ?operationName=... durante l'esecuzione della query.
Quindi, aggiungiamo l'operazione ExecuteAll che dipende sia da RetrieveContentForAdminUser che da RetrieveContentForNonAdminUser, contenente il semplice campo id (perché dobbiamo interrogare qualcosa nell'operazione):
query ExecuteAll
@depends(on: [
"RetrieveContentForAdminUser",
"RetrieveContentForNonAdminUser"
])
{
id
}La chiamata all'endpoint con ?operationName=ExecuteAll caricherà ora entrambe le operazioni, tuttavia solo una di esse verrà effettivamente eseguita.
Rimuovere i dati non necessari
Il passaggio finale consiste nel rimuovere tramite @remove tutti i campi che sono ausiliari (e che quindi non è necessario stampare nella risposta).
La query GraphQL consolidata è:
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
}