Lektion 25: Daten einer externen API transformieren
Diese Tutorial-Lektion zeigt Beispiele zur Anpassung der Antwort einer externen API an beliebige Formate.
Standardwerte und zusĂ€tzliche Eigenschaften zu jedem Eintrag hinzufĂŒgen
Der REST-API-Endpunkt newapi.getpop.org/wp-json/wp/v2/users/?_fields=id,name,url liefert Benutzerdaten, wobei einige Benutzer die Eigenschaft url leer haben:
[
{
"id": 1,
"name": "leo",
"url": "https://leoloso.com"
},
{
"id": 7,
"name": "Test",
"url": ""
},
{
"id": 2,
"name": "Theme Demos",
"url": ""
}
]Die folgende GraphQL-Query transformiert diese Antwort:
- Indem ein Standard-URL fĂŒr Benutzer hinzugefĂŒgt wird, deren Eigenschaft
urlleer ist - Indem jedem Benutzereintrag eine Eigenschaft
linkhinzugefĂŒgt wird (zusammengesetzt aus dem Namen und der URL des Benutzers)
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
)
}Die Antwort lautet:
{
"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>"
}
]
}
}KompositionsfĂ€hige Direktiven können eine oder mehrere Direktiven in sich verschachteln. Wenn mehr als eine verschachtelt wird, wird dies ĂŒber das Argument affectDirectivesUnderPos angegeben, das die relativen Positionen von dieser Direktive zu ihren verschachtelten Direktiven enthĂ€lt.
In der obigen GraphQL-Query ist die Direktive @underEachArrayItem (bereitgestellt von der Erweiterung Field Value Iteration and Manipulation) eine kompositionsfÀhige Direktive. Bei ihrem ersten Vorkommen verschachtelt sie nur eine Direktive, und das Argument affectDirectivesUnderPos kann weggelassen werden:
@underEachArrayItem
@underJSONObjectProperty(
# ...
)(Ăbrigens: Beachte, dass @underJSONObjectProperty ebenfalls eine kompositionsfĂ€hige Direktive ist, die die Direktive @default verschachtelt.)
Bei ihrem zweiten Vorkommen verschachtelt sie die 4 Direktiven zu ihrer Rechten, wie durch das Argument affectDirectivesUnderPos mit dem Wert [1, 2, 3, 4] angegeben:
@underEachArrayItem(
affectDirectivesUnderPos: [1, 2, 3, 4],
# ...
)
@applyField(
name: "_objectProperty",
# ...
)
@applyField(
name: "_objectProperty",
# ...
)
@applyField(
name: "_sprintf",
# ...
)
@applyField(
name: "_objectAddEntry",
# ...
)đ„ Tipps:
Die Direktive @applyField (bereitgestellt von der Erweiterung Field on Field) hat zwei mögliche Ziele fĂŒr ihre Ausgabe:
- Das Argument
passOnwardsAs: "someVariableName"weist den neuen Wert der dynamischen Variable$someVariableNamezu, von der er von den nachfolgenden verschachtelten Direktiven gelesen werden kann:
@applyField(
name: "_objectProperty",
arguments: {
object: $userListItem,
by: {
key: "name"
}
},
passOnwardsAs: "userName"
)- Das Argument
setResultInResponse: trueweist den neuen Wert wieder dem Feld zu (und modifiziert damit die Antwort):
@applyField(
name: "_objectAddEntry",
arguments: {
object: $userListItem,
key: "link",
value: $userLink
},
setResultInResponse: true
)Eine bestimmte Eigenschaft aus den JSON-Objekten extrahieren
Der REST-API-Endpunkt newapi.getpop.org/wp-json/newsletter/v1/subscriptions liefert eine Sammlung von E-Mail-Abonnementdaten, einschlieĂlich der E-Mail-Adresse und der Sprache des Abonnenten:
[
{
"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"
}
]Diese GraphQL-Query gibt nur die E-Mail-Adressen aus der API-Antwort aus, indem sie die Eigenschaft email aus jedem Eintrag extrahiert und den Feldwert damit ersetzt:
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
)
}Die Antwort lautet:
{
"data": {
"emails": [
"abracadabra@ganga.com",
"longon@caramanon.com",
"rancotanto@parabara.com",
"quezarapadon@quebrulacha.net",
"test@test.com",
"emilanga@pedrola.com"
]
}
}Feldwerte bedingt Àndern
Dieses Beispiel baut auf dem vorherigen auf und konvertiert zusÀtzlich das Format der E-Mail-Adressen in der Antwort.
Die folgende GraphQL-Query extrahiert die E-Mail-Adressen aus der API-Antwort und konvertiert jene von Benutzern, deren Sprache Englisch oder Deutsch ist, in GroĂbuchstaben â mithilfe der kompositionsfĂ€higen Direktive @if (bereitgestellt von der Erweiterung 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
}Die Antwort lautet:
{
"data": {
"emails": [
"ABRACADABRA@GANGA.COM",
"longon@caramanon.com",
"RANCOTANTO@PARABARA.COM",
"quezarapadon@quebrulacha.net",
"TEST@TEST.COM",
"emilanga@pedrola.com"
]
}
}Die AusfĂŒhrung bedingter Logik in Gato GraphQL kann dynamisch gestaltet werden: Indem eine dynamische Variable an @if(condition:) (und auch an @unless(condition:)) ĂŒbergeben wird, die am abgefragten Objekt ausgewertet wurde, wird die Logik je nach den Bedingungen dieser EntitĂ€t ausgefĂŒhrt oder nicht.
Auf diese Weise können wir die Antwort fĂŒr bestimmte EntitĂ€ten (und nicht fĂŒr andere) dynamisch Ă€ndern, basierend auf Bedingungen wie:
- Hat der Beitrag Kommentare?
- Hat der Kommentar Antworten?
- Ist der Benutzer ein Administrator?
- Ist das Tag/die Kategorie einem Beitrag zugewiesen?
- Usw.