Pelajaran 5: Menyesuaikan konten untuk pengguna berbeda
Kita dapat mengambil respons berbeda pada sebuah field tergantung pada sebagian data yang di-query, seperti peran pengguna yang sedang login.
Query GraphQL untuk menyesuaikan konten bagi pengguna berbeda
Query GraphQL ini mengambil konten posting, menambahkan tautan "Edit posting ini" di bagian bawah konten hanya untuk pengguna admin:
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
}Untuk pengguna admin, responsnya akan berupa:
{
"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>"
}
}
}Untuk pengguna non-admin, responsnya akan berupa:
{
"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"
}
}
}Membiarkan server GraphQL (dengan mempertimbangkan semua kemungkinan kondisi) menghitung secara dinamis nilai yang diperlukan untuk sebuah field:
- Menyederhanakan logika aplikasi, karena ada satu sumber kebenaran tunggal, kode menjadi DRY, dan klien tidak perlu lagi mengimplementasikan logika yang bersangkutan
- Membuat aplikasi lebih andal, terutama ketika beberapa klien mengakses data dari server, karena implementasi yang berbeda dari logika yang sama bisa tidak identik, yang berpotensi menyebabkan bug (lebih lagi ketika klien berbasis teknologi yang berbeda, seperti JavaScript untuk website, Java untuk aplikasi Android, Swift untuk aplikasi iPhone, dan lainnya)
Langkah demi langkah: membuat query GraphQL
Berikut adalah analisis terperinci tentang cara kerja query tersebut.
Mengetahui apakah pengguna adalah admin
Query ini memeriksa apakah pengguna yang sedang login memiliki peran "administrator", dan mengekspor kondisi ini ke dalam variabel dinamis $isAdminUser:
query
{
me {
roleNames
isAdminUser: _inArray(
value: "administrator",
array: $__roleNames
)
@export(as: "isAdminUser")
}
}Eksekusi kondisional operasi
Ketika Multiple Query Execution diaktifkan, direktif @include dan @skip juga dapat diterapkan pada operasi. Dengan cara ini, kita dapat mengeksekusi atau tidak suatu operasi tergantung pada nilai dari suatu variabel dinamis.
Dalam query di bawah ini, hanya satu dari dua operasi yang akan dieksekusi:
RetrieveContentForAdminUserdieksekusi hanya ketika$isAdminUserbernilaitrueRetrieveContentForNonAdminUserdieksekusi hanya ketika$isAdminUserbernilaifalse
query RetrieveContentForAdminUser
@depends(on: "ExportConditionalVariables")
@include(if: $isAdminUser)
{
# ...
}
query RetrieveContentForNonAdminUser
@depends(on: "ExportConditionalVariables")
@skip(if: $isAdminUser)
{
# ...
}Mari kita berikan dua respons berbeda untuk field content posting tergantung pada apakah pengguna adalah admin atau bukan:
- Operasi pertama menggunakan
contentsebagai alias, dan menghitung nilai field secara dinamis, menggabungkan fieldoriginalContentdanwpAdminEditURLmelalui_sprintf - Operasi kedua mengambil field
contentsecara langsung
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
}
}Menambahkan operasi yang akan dieksekusi
Sekarang kita memiliki dua operasi yang mungkin dieksekusi, namun kita hanya dapat memberikan satu ?operationName=... saat mengeksekusi query.
Maka, kita tambahkan operasi ExecuteAll yang bergantung pada RetrieveContentForAdminUser dan RetrieveContentForNonAdminUser, yang berisi field sederhana id (karena kita harus meng-query sesuatu dalam operasi):
query ExecuteAll
@depends(on: [
"RetrieveContentForAdminUser",
"RetrieveContentForNonAdminUser"
])
{
id
}Memanggil endpoint dengan ?operationName=ExecuteAll sekarang akan memuat kedua operasi, namun hanya satu di antaranya yang akan benar-benar dieksekusi.
Menghapus data yang tidak diperlukan
Langkah terakhir adalah menghapus semua field yang bersifat tambahan (dan karenanya tidak perlu dicetak outputnya dalam respons) melalui @remove.
Query GraphQL yang sudah terkonsolidasi adalah:
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
}