Pelajaran 25: Mengubah data dari API eksternal
Pelajaran tutorial ini mendemonstrasikan contoh-contoh tentang cara mengadaptasi respons dari API eksternal menjadi apa pun yang kita butuhkan.
Menambahkan nilai default dan properti tambahan ke setiap entri
Endpoint REST API newapi.getpop.org/wp-json/wp/v2/users/?_fields=id,name,url menghasilkan data pengguna, dengan beberapa pengguna memiliki properti url yang kosong:
[
{
"id": 1,
"name": "leo",
"url": "https://leoloso.com"
},
{
"id": 7,
"name": "Test",
"url": ""
},
{
"id": 2,
"name": "Theme Demos",
"url": ""
}
]Query GraphQL di bawah ini mengubah respons tersebut:
- Menambahkan URL default untuk pengguna yang properti
url-nya kosong - Menambahkan properti
linkke setiap entri pengguna (disusun menggunakan nilai nama dan URL pengguna)
query {
# Retrieve data from the external API
usersWithLinkAndDefaultURL: _sendJSONObjectCollectionHTTPRequest(
input: {
url: "https://newapi.getpop.org/wp-json/wp/v2/users/?_fields=id,name,url"
}
)
# Set a default URL for users without any
@underEachArrayItem
@underJSONObjectProperty(
by: {
key: "url"
}
)
@default(
value: "https://mysite.com"
condition: IS_EMPTY
)
# Add a new "link" entry on the JSON object
@underEachArrayItem(
affectDirectivesUnderPos: [1, 2, 3, 4],
passValueOnwardsAs: "userListItem"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $userListItem,
by: {
key: "name"
}
},
passOnwardsAs: "userName"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $userListItem,
by: {
key: "url"
}
},
passOnwardsAs: "userURL"
)
@applyField(
name: "_sprintf",
arguments: {
string: "<a href=\"%s\">%s</a>",
values: [$userURL, $userName]
},
passOnwardsAs: "userLink"
)
@applyField(
name: "_objectAddEntry",
arguments: {
object: $userListItem,
key: "link",
value: $userLink
},
setResultInResponse: true
)
}Responsnya adalah:
{
"data": {
"usersWithLinkAndDefaultURL": [
{
"id": 1,
"name": "leo",
"url": "https://leoloso.com",
"link": "<a href=\"https://leoloso.com\">leo</a>"
},
{
"id": 7,
"name": "Test",
"url": "https://mysite.com",
"link": "<a href=\"https://mysite.com\">Test</a>"
},
{
"id": 2,
"name": "Theme Demos",
"url": "https://mysite.com",
"link": "<a href=\"https://mysite.com\">Theme Demos</a>"
}
]
}
}Composable directives dapat menumpuk satu atau lebih direktif di dalamnya. Saat menumpuk lebih dari satu, kita menunjukkan hal ini melalui argumen affectDirectivesUnderPos, yang berisi posisi relatif dari direktif tersebut ke direktif-direktif yang ditumpuknya.
Dalam query GraphQL di atas, direktif @underEachArrayItem (disediakan oleh ekstensi Field Value Iteration and Manipulation) adalah composable directive. Pada kemunculan pertamanya, direktif ini hanya menumpuk satu direktif, dan argumen affectDirectivesUnderPos dapat dihilangkan:
@underEachArrayItem
@underJSONObjectProperty(
# ...
)(Omong-omong, perhatikan bahwa @underJSONObjectProperty juga merupakan composable directive, yang menumpuk direktif @default).
Pada kemunculan keduanya, direktif ini menumpuk 4 direktif di sebelah kanannya, sebagaimana ditunjukkan oleh argumen affectDirectivesUnderPos dengan nilai [1, 2, 3, 4]:
@underEachArrayItem(
affectDirectivesUnderPos: [1, 2, 3, 4],
# ...
)
@applyField(
name: "_objectProperty",
# ...
)
@applyField(
name: "_objectProperty",
# ...
)
@applyField(
name: "_sprintf",
# ...
)
@applyField(
name: "_objectAddEntry",
# ...
)🔥 Tips:
Direktif @applyField (disediakan oleh ekstensi Field on Field) memiliki dua tujuan potensial untuk outputnya:
- Memberikan argumen
passOnwardsAs: "someVariableName"akan menetapkan nilai baru ke variabel dinamis$someVariableName, yang dapat dibaca oleh direktif-direktif bertumpuk berikutnya:
@applyField(
name: "_objectProperty",
arguments: {
object: $userListItem,
by: {
key: "name"
}
},
passOnwardsAs: "userName"
)- Memberikan argumen
setResultInResponse: trueakan menetapkan nilai baru kembali ke field (sehingga akan mengubah respons):
@applyField(
name: "_objectAddEntry",
arguments: {
object: $userListItem,
key: "link",
value: $userLink
},
setResultInResponse: true
)Mengekstrak properti tertentu dari objek JSON
Endpoint REST API newapi.getpop.org/wp-json/newsletter/v1/subscriptions menghasilkan kumpulan data langganan email, termasuk email dan bahasa pelanggan:
[
{
"email": "abracadabra@ganga.com",
"lang": "de"
},
{
"email": "longon@caramanon.com",
"lang": "es"
},
{
"email": "rancotanto@parabara.com",
"lang": "en"
},
{
"email": "quezarapadon@quebrulacha.net",
"lang": "fr"
},
{
"email": "test@test.com",
"lang": "de"
},
{
"email": "emilanga@pedrola.com",
"lang": "fr"
}
]Query GraphQL ini hanya mencetak email dari respons API, dengan mengekstrak properti email dari setiap entri dan mengganti nilai field dengan properti tersebut:
query {
emails: _sendJSONObjectCollectionHTTPRequest(
input: {
url: "https://newapi.getpop.org/wp-json/newsletter/v1/subscriptions"
}
)
@underEachArrayItem(
passValueOnwardsAs: "userEntry"
)
@applyField(
name: "_objectProperty"
arguments: {
object: $userEntry,
by: {
key: "email"
}
}
setResultInResponse: true
)
}Responsnya adalah:
{
"data": {
"emails": [
"abracadabra@ganga.com",
"longon@caramanon.com",
"rancotanto@parabara.com",
"quezarapadon@quebrulacha.net",
"test@test.com",
"emilanga@pedrola.com"
]
}
}Memodifikasi nilai field secara kondisional
Contoh ini melanjutkan contoh sebelumnya, sekaligus juga mengonversi format email dalam respons.
Query GraphQL di bawah ini mengekstrak email dari respons API, dan mengonversi ke huruf kapital email dari pengguna yang bahasanya adalah Inggris atau Jerman melalui composable directive @if (disediakan oleh ekstensi Conditional Field Manipulation):
query {
# Retrieve data from a REST API endpoint
userEntries: _sendJSONObjectCollectionHTTPRequest(
input: {
url: "https://newapi.getpop.org/wp-json/newsletter/v1/subscriptions"
}
)
@remove
emails: _echo(value: $__userEntries)
# Iterate all the entries, passing every entry
# (under the dynamic variable $userEntry)
# to each of the next 4 directives
@underEachArrayItem(
passValueOnwardsAs: "userEntry"
affectDirectivesUnderPos: [1, 2, 3, 4]
)
# Extract property "lang" from the entry
# via the functionality field `_objectProperty`,
# and pass it onwards as dynamic variable $userLang
@applyField(
name: "_objectProperty"
arguments: {
object: $userEntry,
by: {
key: "lang"
}
}
passOnwardsAs: "userLang"
)
# Execute functionality field `_inArray` to find out
# if $userLang is either "en" or "de", and place the
# result under dynamic variable $isSpecialLang
@applyField(
name: "_inArray"
arguments: {
value: $userLang,
array: ["en", "de"]
}
passOnwardsAs: "isSpecialLang"
)
# Extract property "email" from the entry
# and set it back as the value for that entry
@applyField(
name: "_objectProperty"
arguments: {
object: $userEntry,
by: {
key: "email"
}
}
setResultInResponse: true
)
# If $isSpecialLang is `true` then execute
# directive `@strUpperCase`
@if(condition: $isSpecialLang)
@strUpperCase
}Responsnya adalah:
{
"data": {
"emails": [
"ABRACADABRA@GANGA.COM",
"longon@caramanon.com",
"RANCOTANTO@PARABARA.COM",
"quezarapadon@quebrulacha.net",
"TEST@TEST.COM",
"emilanga@pedrola.com"
]
}
}Menjalankan logika kondisional di Gato GraphQL dapat dibuat dinamis: Dengan meneruskan variabel dinamis ke @if(condition:) (dan juga ke @unless(condition:)) yang dievaluasi pada objek yang di-query, logika akan dijalankan atau tidak tergantung pada kondisi dari entitas tersebut.
Dengan cara ini, kita dapat memodifikasi respons secara dinamis untuk beberapa entitas (dan tidak untuk yang lain), berdasarkan kondisi seperti:
- Apakah postingan memiliki komentar?
- Apakah komentar memiliki balasan?
- Apakah pengguna adalah admin?
- Apakah tag/kategori diterapkan pada suatu postingan?
- Dll