Lição 20: Combinando dados de usuário de diferentes fontes
Na lição anterior do tutorial, aprendemos que podemos buscar dados de usuário da API REST do Mailchimp e combiná-los com os dados de usuário armazenados em nosso site.
Podemos generalizar essa ideia, aplicando-a a qualquer par de fontes de dados, combinando seus datasets em um único, e então executando alguma operação com os dados combinados.
Combinando datasets de diferentes fontes
O campo de função _arrayInnerJoinJSONObjectProperties (fornecido pela extensão PHP Functions Via Schema) nos permite combinar objetos JSON que referenciam a mesma entidade em um único objeto JSON contendo todas as propriedades.
Os objetos JSON em ambas as fontes podem ser identificados como referências à mesma entidade porque sua propriedade "índice" tem o mesmo valor.
Nesta query GraphQL, os inputs source e target recebem listas de objetos JSON que compartilham uma propriedade comum email (usada como "índice"):
query {
_arrayInnerJoinJSONObjectProperties(
source: [
{
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"
}
],
target: [
{
email: "quezarapadon@quebrulacha.net",
name: "Abrigail Ataluncha"
},
{
email: "abracadabra@ganga.com",
name: "Chip Bennett"
},
{
email: "contributor@test.com",
name: "Contributor"
},
{
email: "longon@caramanon.com",
name: "Emil Uzelac"
},
{
email: "rancotanto@parabara.com",
name: "Lance Ampsrong"
},
{
email: "leo@getpop.org",
name: "leo"
},
{
email: "test@test.com",
name: "Test"
},
{
email: "emilanga@pedrola.com",
name: "Theme Demos"
}
],
index: "email"
)
}Quando o valor da propriedade email é igual nos objetos JSON de origem e destino, esses objetos são combinados na lista resultante:
{
"data": {
"_arrayInnerJoinJSONObjectProperties": [
{
"email": "quezarapadon@quebrulacha.net",
"name": "Abrigail Ataluncha",
"lang": "fr"
},
{
"email": "abracadabra@ganga.com",
"name": "Chip Bennett",
"lang": "de"
},
{
"email": "contributor@test.com",
"name": "Contributor"
},
{
"email": "longon@caramanon.com",
"name": "Emil Uzelac",
"lang": "es"
},
{
"email": "rancotanto@parabara.com",
"name": "Lance Ampsrong",
"lang": "en"
},
{
"email": "leo@getpop.org",
"name": "leo"
},
{
"email": "test@test.com",
"name": "Test",
"lang": "de"
},
{
"email": "emilanga@pedrola.com",
"name": "Theme Demos",
"lang": "fr"
}
]
}
}Podemos recuperar dados armazenados em múltiplos serviços baseados em nuvem (acessíveis via APIs desses serviços) e combinar esses datasets distintos em um único.
Por exemplo, escolha dois desses serviços que possam armazenar dados de usuário:
- Mailchimp
- Dropbox
- GitHub
- Microsoft Teams
- Slack
- Trello
- Google Drive
- Seu site WordPress
- As aplicações internas da sua empresa
- etc
A query GraphQL abaixo combina os datasets de dois serviços hipotéticos:
- Um sistema de newsletter (armazenando dados dos assinantes, incluindo email e idioma falado)
- Um CRM (armazenando dados dos clientes, incluindo nome e email)
Ela primeiro busca todos os registros do serviço de newsletter e extrai os emails. Em seguida, usa esses emails para gerar a URL do endpoint da API REST do CRM, a fim de buscar dados apenas para esses usuários. Por fim, combina ambos os datasets em um único, ao redor da propriedade compartilhada email:
query ProvideNewsletterUserData {
userList: _sendJSONObjectCollectionHTTPRequest(
input: {
url: "https://newapi.getpop.org/wp-json/newsletter/v1/subscriptions"
}
)
@export(as: "userList")
userEmails: _echo(value: $__userList)
@underEachArrayItem(passValueOnwardsAs: "userListItemForEmail")
@applyField(
name: "_objectProperty",
arguments: {
object: $userListItemForEmail,
by: {
key: "email"
}
},
setResultInResponse: true
)
@export(as: "userEmails")
}
query CombineUserDataFromDisparateSources
@depends(on: "ProvideNewsletterUserData")
{
joinedUserEmails: _arrayJoin(
array: $userEmails,
separator: "&emails[]="
)
userEndpoint: _strAppend(
after: "https://newapi.getpop.org/users/api/rest/?query={name%20email}&emails[]=",
append: $__joinedUserEmails
)
userEndpointDataItems: _sendJSONObjectCollectionHTTPRequest(
input: {
url: $__userEndpoint
}
)
userData: _arrayInnerJoinJSONObjectProperties(
source: $__userEndpointDataItems,
target: $userList,
index: "email"
)
@export(as: "userData")
}...produzindo:
{
"data": {
"userList": [
{
"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"
}
],
"userEmails": [
"abracadabra@ganga.com",
"longon@caramanon.com",
"rancotanto@parabara.com",
"quezarapadon@quebrulacha.net",
"test@test.com",
"emilanga@pedrola.com"
],
"joinedUserEmails": "abracadabra@ganga.com&emails[]=longon@caramanon.com&emails[]=rancotanto@parabara.com&emails[]=quezarapadon@quebrulacha.net&emails[]=test@test.com&emails[]=emilanga@pedrola.com",
"userEndpoint": "https://newapi.getpop.org/users/api/rest/?query={name%20email}&emails[]=abracadabra@ganga.com&emails[]=longon@caramanon.com&emails[]=rancotanto@parabara.com&emails[]=quezarapadon@quebrulacha.net&emails[]=test@test.com&emails[]=emilanga@pedrola.com",
"userEndpointDataItems": [
{
"name": "Abrigail Ataluncha",
"email": "quezarapadon@quebrulacha.net"
},
{
"name": "Chip Bennett",
"email": "abracadabra@ganga.com"
},
{
"name": "Contributor",
"email": "contributor@test.com"
},
{
"name": "Emil Uzelac",
"email": "longon@caramanon.com"
},
{
"name": "Lance Ampsrong",
"email": "rancotanto@parabara.com"
},
{
"name": "leo",
"email": "leo@getpop.org"
},
{
"name": "Test",
"email": "test@test.com"
},
{
"name": "Theme Demos",
"email": "emilanga@pedrola.com"
}
],
"userData": [
{
"email": "abracadabra@ganga.com",
"lang": "de",
"name": "Chip Bennett"
},
{
"email": "longon@caramanon.com",
"lang": "es",
"name": "Emil Uzelac"
},
{
"email": "rancotanto@parabara.com",
"lang": "en",
"name": "Lance Ampsrong"
},
{
"email": "quezarapadon@quebrulacha.net",
"lang": "fr",
"name": "Abrigail Ataluncha"
},
{
"email": "test@test.com",
"lang": "de",
"name": "Test"
},
{
"email": "emilanga@pedrola.com",
"lang": "fr",
"name": "Theme Demos"
}
]
}
}