Ders 5: Farklı kullanıcılara göre içerik özelleştirme
Sorgulanan verinin bir parçasına, örneğin oturum açmış kullanıcının rollerine bağlı olarak bir alanda farklı yanıt alabiliriz.
Farklı kullanıcılara göre içerik özelleştirmek için GraphQL query
Bu GraphQL query, gönderi içeriğini alır ve yalnızca yönetici kullanıcı için içeriğin en altına bir "Bu gönderiyi düzenle" bağlantısı ekler:
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
}Yönetici kullanıcılar için yanıt şu şekilde olacaktır:
{
"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>"
}
}
}Yönetici olmayan kullanıcılar için yanıt şu şekilde olacaktır:
{
"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"
}
}
}GraphQL sunucusunun (tüm olası koşullar göz önüne alınarak) bir alan için gereken değeri dinamik olarak hesaplaması:
- Uygulamanın mantığını basitleştirir; tek bir doğruluk kaynağı bulunur, kod DRY hale gelir ve istemcilerin artık ilgili mantığı uygulaması gerekmez
- Uygulamayı daha güvenilir kılar; özellikle sunucudan veri alan birden fazla istemci olduğunda, aynı mantığın farklı uygulamaları özdeş olmayabilir ve potansiyel olarak hatalara yol açabilir (farklı teknolojilere dayanan istemcilerde — web sitesi için JavaScript, Android uygulaması için Java, iPhone uygulaması için Swift ve diğerleri — bu durum çok daha belirgin hale gelir)
Adım adım: GraphQL query oluşturma
Aşağıda query'nin nasıl çalıştığına dair ayrıntılı analiz yer almaktadır.
Kullanıcının yönetici olup olmadığını öğrenmek
Bu query, oturum açmış kullanıcının "administrator" rolüne sahip olup olmadığını kontrol eder ve bu koşulu $isAdminUser dinamik değişkeni olarak dışa aktarır:
query
{
me {
roleNames
isAdminUser: _inArray(
value: "administrator",
array: $__roleNames
)
@export(as: "isAdminUser")
}
}İşlemlerin koşullu olarak çalıştırılması
Çoklu Query Çalıştırma etkinleştirildiğinde, @include ve @skip direktifleri işlemlere de uygulanabilir. Bu sayede bir işlemi, dinamik bir değişkenin değerine bağlı olarak çalıştırıp çalıştırmamayı belirleyebiliriz.
Aşağıdaki query'de iki işlemden yalnızca biri çalıştırılacaktır:
RetrieveContentForAdminUseryalnızca$isAdminUsertrueolduğunda çalıştırılırRetrieveContentForNonAdminUseryalnızca$isAdminUserfalseolduğunda çalıştırılır
query RetrieveContentForAdminUser
@depends(on: "ExportConditionalVariables")
@include(if: $isAdminUser)
{
# ...
}
query RetrieveContentForNonAdminUser
@depends(on: "ExportConditionalVariables")
@skip(if: $isAdminUser)
{
# ...
}Kullanıcının yönetici olup olmadığına bağlı olarak gönderinin content alanı için iki farklı yanıt sağlayalım:
- İlk işlem
content'i takma ad olarak kullanır ve alanın değerini dinamik olarak hesaplar;originalContentilewpAdminEditURLalanlarını_sprintfaracılığıyla birleştirir - İkinci işlem
contentalanını doğrudan alır
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
}
}Çalıştırılacak işlemi eklemek
Artık çalıştırılabilecek iki işlemimiz var; ancak query'yi çalıştırırken yalnızca bir ?operationName=... sağlayabiliriz.
Bu nedenle, hem RetrieveContentForAdminUser hem de RetrieveContentForNonAdminUser'a bağlı olan ve basit id alanını içeren (çünkü işlemde bir şey sorgulamak zorundayız) ExecuteAll işlemini ekliyoruz:
query ExecuteAll
@depends(on: [
"RetrieveContentForAdminUser",
"RetrieveContentForNonAdminUser"
])
{
id
}Endpoint'i ?operationName=ExecuteAll ile çağırmak artık her iki işlemi de yükleyecek; ancak yalnızca biri gerçekten çalıştırılacaktır.
Gereksiz verileri kaldırmak
Son adım, yardımcı niteliğindeki (dolayısıyla yanıtta çıktılarını yazdırmamız gerekmeyen) tüm alanları @remove aracılığıyla kaldırmaktır.
Birleştirilmiş GraphQL query şu şekildedir:
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
}