Lezione 25: Trasformazione dei dati da un'API esterna
Questa lezione del tutorial illustra esempi di adattamento della risposta di un'API esterna a qualsiasi formato necessario.
Aggiunta di valori predefiniti e proprietà aggiuntive a ogni voce
L'endpoint dell'API REST newapi.getpop.org/wp-json/wp/v2/users/?_fields=id,name,url produce dati sugli utenti, con alcuni utenti che hanno la proprietà url vuota:
[
{
"id": 1,
"name": "leo",
"url": "https://leoloso.com"
},
{
"id": 7,
"name": "Test",
"url": ""
},
{
"id": 2,
"name": "Theme Demos",
"url": ""
}
]La query GraphQL qui sotto trasforma questa risposta:
- Aggiungendo un URL predefinito agli utenti la cui proprietÃ
urlè vuota - Aggiungendo una proprietÃ
linka ogni voce utente (composta usando il nome e l'URL dell'utente)
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
)
}La risposta è:
{
"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>"
}
]
}
}Le direttive componibili possono annidare una o più direttive al loro interno. Quando si annidano più di una, lo si indica tramite l'argomento affectDirectivesUnderPos, che contiene le posizioni relative da quella direttiva alle sue direttive annidate.
Nella query GraphQL sopra, la direttiva @underEachArrayItem (fornita dall'estensione Iterazione e Manipolazione del Valore del Campo) è una direttiva componibile. Alla sua prima occorrenza, annida solo una direttiva, e l'argomento affectDirectivesUnderPos può essere omesso:
@underEachArrayItem
@underJSONObjectProperty(
# ...
)(Tra l'altro, si noti che anche @underJSONObjectProperty è una direttiva componibile, che annida la direttiva @default).
Alla sua seconda occorrenza, annida le 4 direttive alla sua destra, come indicato dall'argomento affectDirectivesUnderPos con valore [1, 2, 3, 4]:
@underEachArrayItem(
affectDirectivesUnderPos: [1, 2, 3, 4],
# ...
)
@applyField(
name: "_objectProperty",
# ...
)
@applyField(
name: "_objectProperty",
# ...
)
@applyField(
name: "_sprintf",
# ...
)
@applyField(
name: "_objectAddEntry",
# ...
)🔥 Suggerimenti:
La direttiva @applyField (fornita dall'estensione Campo su Campo) ha due potenziali destinazioni per il suo output:
- Fornire l'argomento
passOnwardsAs: "someVariableName"assegnerà il nuovo valore alla variabile dinamica$someVariableName, dalla quale potrà essere letta dalle successive direttive annidate:
@applyField(
name: "_objectProperty",
arguments: {
object: $userListItem,
by: {
key: "name"
}
},
passOnwardsAs: "userName"
)- Fornire l'argomento
setResultInResponse: trueassegnerà il nuovo valore nuovamente al campo (modificando quindi la risposta):
@applyField(
name: "_objectAddEntry",
arguments: {
object: $userListItem,
key: "link",
value: $userLink
},
setResultInResponse: true
)Estrazione di una proprietà specifica dagli oggetti JSON
L'endpoint dell'API REST newapi.getpop.org/wp-json/newsletter/v1/subscriptions produce una raccolta di dati di iscrizione via email, inclusi l'email e la lingua dell'iscritto:
[
{
"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"
}
]Questa query GraphQL mostra solo le email dalla risposta dell'API, estraendo la proprietà email da ogni voce e sostituendo il valore del campo con essa:
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
)
}La risposta è:
{
"data": {
"emails": [
"abracadabra@ganga.com",
"longon@caramanon.com",
"rancotanto@parabara.com",
"quezarapadon@quebrulacha.net",
"test@test.com",
"emilanga@pedrola.com"
]
}
}Modifica condizionale dei valori dei campi
Questo esempio si basa sul precedente, aggiungendo anche la conversione del formato delle email nella risposta.
La query GraphQL qui sotto estrae le email dalla risposta dell'API e converte in maiuscolo quelle degli utenti la cui lingua è inglese o tedesca tramite la direttiva componibile @if (fornita dall'estensione Manipolazione Condizionale del Campo):
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
}La risposta è:
{
"data": {
"emails": [
"ABRACADABRA@GANGA.COM",
"longon@caramanon.com",
"RANCOTANTO@PARABARA.COM",
"quezarapadon@quebrulacha.net",
"TEST@TEST.COM",
"emilanga@pedrola.com"
]
}
}L'esecuzione di logica condizionale in Gato GraphQL può essere resa dinamica: passando una variabile dinamica a @if(condition:) (e anche a @unless(condition:)) che è stata valutata sull'oggetto interrogato, la logica verrà eseguita o meno in base alle condizioni di quell'entità .
In questo modo, è possibile modificare dinamicamente la risposta per alcune entità (e non per altre), in base a condizioni quali:
- Il post ha commenti?
- Il commento ha risposte?
- L'utente è un amministratore?
- Il tag/la categoria è applicato a qualche post?
- Ecc.