บทเรียนที่ 20: การรวมข้อมูลผู้ใช้จากแหล่งต่าง ๆ
ในบทเรียนก่อนหน้านี้ เราได้เรียนรู้ว่าเราสามารถดึงข้อมูลผู้ใช้จาก REST API ของ Mailchimp และรวมเข้ากับข้อมูลผู้ใช้ที่เก็บไว้ในเว็บไซต์ของเราได้
เราสามารถนำแนวคิดนี้ไปประยุกต์ใช้กับแหล่งข้อมูลสองแหล่งใด ๆ ก็ได้ โดยรวมชุดข้อมูลของแหล่งเหล่านั้นเข้าเป็นชุดเดียว แล้วดำเนินการบางอย่างกับข้อมูลที่รวมเข้าด้วยกัน
การรวมชุดข้อมูลจากแหล่งต่าง ๆ
ฟิลด์ฟังก์ชัน _arrayInnerJoinJSONObjectProperties (จัดเตรียมโดยส่วนขยาย PHP Functions Via Schema) ช่วยให้เราสามารถรวมออบเจ็กต์ JSON ที่อ้างอิงถึงเอนทิตีเดียวกันเข้าเป็นออบเจ็กต์ JSON เดียวที่มีคุณสมบัติทั้งหมดได้
ออบเจ็กต์ JSON ในทั้งสองแหล่งสามารถระบุได้ว่าอ้างอิงถึงเอนทิตีเดียวกัน เนื่องจากคุณสมบัติ "index" ของออบเจ็กต์เหล่านั้นมีค่าเหมือนกัน
ใน GraphQL query นี้ อินพุต source และ target รับลิสต์ของออบเจ็กต์ JSON ที่มีคุณสมบัติ email ร่วมกัน (จึงถูกใช้เป็น "index"):
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"
)
}เมื่อค่าของคุณสมบัติ email เหมือนกันในออบเจ็กต์ JSON ของ source และ target ออบเจ็กต์เหล่านั้นจะถูกรวมเข้าด้วยกันในลิสต์ผลลัพธ์:
{
"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"
}
]
}
}เราสามารถดึงข้อมูลที่เราเก็บไว้ในบริการบนคลาวด์หลายบริการ (เข้าถึงได้ผ่าน API ของบริการเหล่านั้น) และรวมชุดข้อมูลที่แตกต่างกันเหล่านี้เข้าด้วยกันได้
ตัวอย่างเช่น เลือกสองบริการใด ๆ จากบริการเหล่านี้ที่อาจเก็บข้อมูลผู้ใช้:
- Mailchimp
- Dropbox
- GitHub
- Microsoft Teams
- Slack
- Trello
- Google Drive
- เว็บไซต์ WordPress ของคุณ
- แอปพลิเคชันภายในของบริษัทคุณ
- ฯลฯ
GraphQL query ด้านล่างนี้รวมชุดข้อมูลจากสองบริการสมมติ:
- ระบบจดหมายข่าว (เก็บข้อมูลผู้สมัครสมาชิก รวมถึงอีเมลและภาษาที่ใช้พูด)
- CRM (เก็บข้อมูลลูกค้า รวมถึงชื่อและอีเมล)
ขั้นแรกจะดึงเรคคอร์ดทั้งหมดจากบริการจดหมายข่าวและแยกอีเมลออกมา จากนั้นใช้อีเมลเหล่านี้สร้าง URL ของเอนด์พอยต์สำหรับ REST API ของ CRM เพื่อดึงข้อมูลเฉพาะของผู้ใช้เหล่านั้น สุดท้ายจะรวมชุดข้อมูลทั้งสองเข้าเป็นชุดเดียวรอบ ๆ คุณสมบัติ 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")
}...ซึ่งให้ผลลัพธ์เป็น:
{
"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"
}
]
}
}