การวนซ้ำและการจัดการค่าของฟิลด์
การเพิ่มเมตาไดเรกทีฟให้กับ GraphQL schema เพื่อวนซ้ำและจัดการองค์ประกอบค่าของฟิลด์ประเภท array และ object:
@underArrayItem@underJSONObjectProperty@underEachArrayItem@underEachJSONObjectProperty@objectClone
@underArrayItem
@underArrayItem ทำให้ไดเรกทีฟที่ซ้อนอยู่ถูกนำไปใช้กับองค์ประกอบที่ระบุภายใน array
ในเควรีด้านล่าง มีเพียงองค์ประกอบแรกใน array ของชื่อหมวดหมู่เท่านั้นที่ถูกแปลงเป็นตัวพิมพ์ใหญ่:
query {
posts {
categoryNames
@underArrayItem(index: 0)
@strUpperCase
}
}...ซึ่งให้ผลลัพธ์:
{
"data": {
"posts": {
"categoryNames": [
"NEWS",
"sports"
]
}
}
}@underJSONObjectProperty
@underJSONObjectProperty ทำให้ไดเรกทีฟที่ซ้อนอยู่ได้รับเอนทรีจาก JSON object ที่ถูกเควรี
ไดเรกทีฟนี้มีประโยชน์อย่างยิ่งในการดึงและจัดการข้อมูลที่ต้องการหลังจากเควรี API ภายนอก ซึ่งมักจะมีประเภทเป็น JSONObject แบบทั่วไป (เช่นเมื่อใช้ฟังก์ชันฟิลด์ _sendJSONObjectItemHTTPRequest จากเอ็กซ์เทนชัน HTTP Client)
ในเควรีด้านล่าง เราได้รับ JSON object จาก WP REST API และเราใช้ @underJSONObjectProperty เพื่อจัดการพร็อพเพอร์ตี type ของการตอบกลับ โดยแปลงเป็นตัวพิมพ์ใหญ่:
query {
postData: _sendJSONObjectItemHTTPRequest(input: {
url: "https://newapi.getpop.org/wp-json/wp/v2/posts/1/?_fields=id,type,title,date"
})
@underJSONObjectProperty(by: { key: "type" })
@strUpperCase
}ซึ่งจะให้ผลลัพธ์ดังนี้:
{
"data": {
"postData": {
"id": 1,
"date": "2019-08-02T07:53:57",
"type": "POST",
"title": {
"rendered": "Hello world!"
}
}
}
}นอกจากการรับ "key" เพื่อชี้ไปยังพร็อพเพอร์ตีที่อยู่ในระดับแรกของ JSON object แล้ว ไดเรกทีฟนี้ยังสามารถรับ "path" เพื่อนำทางภายในโครงสร้างของ object โดยใช้ . เป็นตัวคั่นระหว่างระดับได้อีกด้วย
ในเควรีด้านล่าง เอนด์พอยต์ WP REST API สำหรับโพสต์ให้พร็อพเพอร์ตี "title.rendered" มา เราสามารถนำทางไปยังซับอิลิเมนต์นั้นจริง ๆ และแปลงให้เป็นแบบ title case ได้:
query {
postData: _sendJSONObjectItemHTTPRequest(input: {
url: "https://newapi.getpop.org/wp-json/wp/v2/posts/1/?_fields=id,type,title,date"
})
@underJSONObjectProperty(by: { path: "title.rendered" })
@strTitleCase
}ซึ่งจะให้ผลลัพธ์ดังนี้:
{
"data": {
"postData": {
"id": 1,
"date": "2019-08-02T07:53:57",
"type": "post",
"title": {
"rendered": "HELLO WORLD!"
}
}
}
}@underEachArrayItem
@underEachArrayItem วนซ้ำองค์ประกอบ array จากฟิลด์บางตัวในเอนทิตีที่ถูกเควรี และเรียกใช้ไดเรกทีฟที่ซ้อนอยู่กับแต่ละองค์ประกอบ
ตัวอย่างเช่น ฟิลด์ Post.categoryNames มีประเภทเป็น [String] เมื่อใช้ @underEachArrayItem เราสามารถวนซ้ำชื่อหมวดหมู่และนำไดเรกทีฟ @strTranslate ไปใช้กับชื่อเหล่านั้นได้
ในเควรีนี้ หมวดหมู่ของโพสต์ถูกแปลจากภาษาอังกฤษเป็นภาษาฝรั่งเศส:
query {
posts {
id
title
categoryNames
@underEachArrayItem
@strTranslate(
from: "en",
to: "fr"
)
}
}...ซึ่งให้ผลลัพธ์:
{
"data": {
"posts": [
{
"id": 662,
"title": "Explaining the privacy policy",
"categoryNames": [
"Non classé"
]
},
{
"id": 28,
"title": "HTTP caching improves performance",
"categoryNames": [
"Avancé"
]
},
{
"id": 25,
"title": "Public or Private API mode, for extra security",
"categoryNames": [
"Ressource",
"Blog",
"Avancé"
]
}
]
}
}@underEachArrayItem สามารถส่งทั้งดัชนีและค่าขององค์ประกอบที่กำลังวนซ้ำเป็นตัวแปรไดนามิกไปยังไดเรกทีฟที่ซ้อนอยู่ ผ่านอาร์กิวเมนต์ไดเรกทีฟ passIndexOnwardsAs และ passValueOnwardsAs
เควรีนี้แสดงตัวอย่างการใช้ตัวแปรไดนามิก $index และ $value:
{
_echo(value: ["first", "second", "third"])
@underEachArrayItem(
passIndexOnwardsAs: "index"
passValueOnwardsAs: "value"
)
@applyField(
name: "_echo"
arguments: {
value: {
index: $index,
value: $value
}
},
setResultInResponse: true
)
}ผลลัพธ์คือ:
{
"data": {
"_echo": [
{
"index": 0,
"value": "first"
},
{
"index": 1,
"value": "second"
},
{
"index": 2,
"value": "third"
}
]
}
}@underEachArrayItem ยังสามารถจำกัดตำแหน่งของ array ที่จะวนซ้ำได้ ผ่านพารามิเตอร์ filter->by ซึ่งสามารถรับเอนทรี include หรือ exclude ก็ได้
เควรีนี้:
{
including: _echo([
"first",
"second",
"third"
])
@underEachArrayItem(
filter: {
by: {
include: [0, 2]
}
}
)
@strUpperCase
excluding: _echo([
"first",
"second",
"third"
])
@underEachArrayItem(
filter: {
by: {
exclude: [0, 2]
}
}
)
@strUpperCase
}...produces:
{
"data": {
"including": [
"FIRST",
"second",
"THIRD"
],
"excluding": [
"first",
"SECOND",
"third"
]
}
}@underEachJSONObjectProperty
@underEachJSONObjectProperty คล้ายกับ @underEachArrayItem แต่ทำงานกับองค์ประกอบ JSONObject
ในเควรีนี้ เราวนซ้ำทุกเอนทรีใน JSON object และแทนที่เอนทรี null ใด ๆ ด้วยสตริงว่าง:
{
_echo(
value: {
first: "hello",
second: "world",
third: null
}
)
@underEachJSONObjectProperty
@default(value: "")
}...ซึ่งให้ผลลัพธ์:
{
"data": {
"_echo": {
"first": "hello",
"second": "world",
"third": ""
}
}
}@underEachJSONObjectProperty สามารถส่งคีย์และค่าที่กำลังวนซ้ำเป็นตัวแปรไดนามิกไปยังไดเรกทีฟที่ซ้อนอยู่ ผ่านอาร์กิวเมนต์ไดเรกทีฟ passKeyOnwardsAs และ passValueOnwardsAs
เควรีนี้แสดงตัวอย่างการใช้ตัวแปรไดนามิก $key และ $value:
{
_echo(value: {
uno: "first",
dos: "second",
tres: "third"
})
@underEachJSONObjectProperty(
passKeyOnwardsAs: "key"
passValueOnwardsAs: "value"
)
@applyField(
name: "_echo"
arguments: {
value: {
key: $key,
value: $value
}
},
setResultInResponse: true
)
}ผลลัพธ์คือ:
{
"data": {
"_echo": {
"uno": {
"key": "uno",
"value": "first"
},
"dos": {
"key": "dos",
"value": "second"
},
"tres": {
"key": "tres",
"value": "third"
}
}
}
}@underEachJSONObjectProperty ยังสามารถจำกัดคีย์จาก JSON object ที่จะวนซ้ำได้ ผ่านพารามิเตอร์ filter->by ซึ่งสามารถรับเอนทรี includeKeys หรือ excludeKeys ก็ได้
เควรีนี้:
{
includingKeys: _echo(value: {
uno: "first",
dos: "second",
tres: "third"
})
@underEachJSONObjectProperty(
filter: {
by: {
includeKeys: ["uno", "tres"]
}
}
)
@strUpperCase
excludingKeys: _echo(value: {
uno: "first",
dos: "second",
tres: "third"
})
@underEachJSONObjectProperty(
filter: {
by: {
excludeKeys: ["uno", "tres"]
}
}
)
@strUpperCase
}...produces:
{
"data": {
"includingKeys": {
"uno": "FIRST",
"dos": "second",
"tres": "THIRD"
},
"excludingKeys": {
"uno": "first",
"dos": "SECOND",
"tres": "third"
}
}
}@objectClone
JSON object อาจถูกเข้าถึงโดยการอ้างอิงในฟิลด์รีโซลเวอร์ (ไม่ใช่โดยการคัดลอก/ทำสำเนา object) ในกรณีนั้น เมื่อ JSON object ถูกแก้ไข การแก้ไขนี้จะปรากฏให้เห็นในทุกฟิลด์ที่ดึง JSON object นี้
นี่คือกรณีของฟิลด์ Block.attributes:
{
posts {
blocks(filterBy: { include: "core/heading" } ) {
attributes
}
}
}...ซึ่งให้ผลลัพธ์:
{
"data": {
"posts": [
{
"blocks": [
{
"attributes": {
"content": "Image Block (Full width)",
"level": 2
}
},
{
"attributes": {
"content": "Gallery Block",
"level": 2
}
}
]
}
]
}
}ในเควรีด้านล่าง ขณะที่ originalAttributes เพียงแค่ดึงแอตทริบิวต์มา transformedAttributes จะแปลพร็อพเพอร์ตี content เป็นภาษาฝรั่งเศสด้วย:
{
posts {
blocks(filterBy: { include: "core/heading" } ) {
originalAttributes: attributes
transformedAttributes: attributes
@underJSONObjectProperty(by: { key: "content" })
@strTranslate(to: "fr")
}
}
}อย่างไรก็ตาม เนื่องจากเอนทิตี Block ที่ถูกเควรีอ้างอิงไปยัง JSON object เดียวกันทั้งใน originalAttributes และ transformedAttributes การแปลงที่ทำโดยฟิลด์หลังจึงส่งผลต่อฟิลด์แรกด้วย (โดยไม่ขึ้นกับลำดับที่ปรากฏในเควรี)
ผลที่ได้คือ ทั้งสองฟิลด์ถูกแปลเป็นภาษาฝรั่งเศส:
{
"data": {
"posts": [
{
"blocks": [
{
"originalAttributes": {
"content": "Bloc d'image (pleine largeur)",
"level": 2
},
"transformedAttributes": {
"content": "Bloc d'image (pleine largeur)",
"level": 2
}
},
{
"originalAttributes": {
"content": "Bloc Galerie",
"level": 2
},
"transformedAttributes": {
"content": "Bloc Galerie",
"level": 2
}
}
]
}
]
}
}เราสามารถหลีกเลี่ยงปัญหานี้ได้โดยการเพิ่มไดเรกทีฟ @objectClone ลงในฟิลด์ transformedAttributes เพื่อให้การแก้ไขถูกดำเนินการบน JSON object ที่ถูกโคลน:
{
posts {
blocks(filterBy: { include: "core/heading" } ) {
originalAttributes: attributes
transformedAttributes: attributes
@objectClone
@underJSONObjectProperty(by: { key: "content" })
@strTranslate(to: "fr")
}
}
}...ซึ่งให้ผลลัพธ์:
{
"data": {
"posts": [
{
"blocks": [
{
"originalAttributes": {
"content": "Image Block (Full width)",
"level": 2
},
"transformedAttributes": {
"content": "Bloc d'image (pleine largeur)",
"level": 2
}
},
{
"originalAttributes": {
"content": "Gallery Block",
"level": 2
},
"transformedAttributes": {
"content": "Bloc Galerie",
"level": 2
}
}
]
}
]
}
}ตัวอย่างเพิ่มเติม
ในเควรีนี้ @underEachArrayItem ห่อหุ้ม @underJSONObjectProperty ซึ่งห่อหุ้ม @strUpperCase อีกที โดยแปลงพร็อพเพอร์ตี "title.rendered" เป็นตัวพิมพ์ใหญ่ สำหรับโพสต์หลายรายการที่ได้รับผ่าน WP REST API:
query {
postListData: _sendJSONObjectCollectionHTTPRequest(
url: "https://newapi.getpop.org/wp-json/wp/v2/posts/?per_page=3&_fields=id,type,title,date"
)
@underEachArrayItem
@underJSONObjectProperty(by: { path: "title.rendered" })
@strUpperCase
}...ซึ่งให้ผลลัพธ์:
{
"data": {
"postListData": [
{
"id": 1692,
"date": "2022-04-26T10:10:08",
"type": "post",
"title": {
"rendered": "MY BLOGROLL"
}
},
{
"id": 1657,
"date": "2020-12-21T08:24:18",
"type": "post",
"title": {
"rendered": "A TALE OF TWO CITIES – TEASER"
}
},
{
"id": 1499,
"date": "2019-08-08T02:49:36",
"type": "post",
"title": {
"rendered": "COPE WITH WORDPRESS: POST DEMO CONTAINING PLENTY OF BLOCKS"
}
}
]
}
}