บทช่วยสอน Schema
บทช่วยสอน Schemaบทเรียนที่ 20: การรวมข้อมูลผู้ใช้จากแหล่งต่าง ๆ

บทเรียนที่ 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 ด้านล่างนี้รวมชุดข้อมูลจากสองบริการสมมติ:

  1. ระบบจดหมายข่าว (เก็บข้อมูลผู้สมัครสมาชิก รวมถึงอีเมลและภาษาที่ใช้พูด)
  2. 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"
      }
    ]
  }
}