GraphQL
GraphQL เป็นภาษา query ที่ให้ไคลเอนต์ส่ง query เพื่อเข้าถึงหรือแก้ไขข้อมูลได้ เช่นเดียวกับ SQL, GraphQL ยอมให้ query เหล่านี้ถูกเปลี่ยนแปลงแบบ dynamic ทำให้ไคลเอนต์กำหนดได้เองว่าต้องการข้อมูลอะไรกลับมาอย่างแม่นยำ ด้วยการเรียก REST over HTTP แบบมาตรฐาน ตัวอย่างเช่น เมื่อส่ง GET request สำหรับ resource Order คุณจะได้ field ทั้งหมดของ order นั้นกลับมา แต่ถ้าในสถานการณ์เฉพาะนั้นคุณต้องการแค่ยอดรวมของ order ล่ะ คุณอาจแค่เพิกเฉยต่อ field อื่นๆ หรือไม่ก็มี resource ทางเลือก (อาจเป็น Order Summary ) ที่มีแค่ข้อมูลที่คุณต้องการ ด้วย GraphQL คุณสามารถส่ง request ขอเฉพาะ field ที่คุณต้องการได้ ดังที่เราเห็นใน Example 14-1
Example 14-1. ตัวอย่าง GraphQL query ที่ใช้ดึงข้อมูล order
{
order(id: 123) {
date
total
status
delivery {
company
driver
duedate
}
}
}
ใน query นี้ เราขอ order 123 และเราขอราคารวมกับสถานะของ order นั้นด้วย เรายังไปไกลกว่านั้นและขอข้อมูลเกี่ยวกับการจัดส่งของ order นี้ ทำให้เราได้ข้อมูลเกี่ยวกับชื่อของคนขับที่จะจัดส่งพัสดุของเรา บริษัทที่พวกเขาทำงานให้ และเวลาที่คาดว่าพัสดุจะมาถึง ด้วย REST API ทั่วไป เว้นแต่ข้อมูลการจัดส่งจะอยู่ใน resource Order อยู่แล้ว เราอาจต้องเรียกเพิ่มเติมอีกครั้งเพื่อดึงข้อมูลนี้ ดังนั้น GraphQL ไม่ได้แค่ช่วยให้เราขอเฉพาะ field ที่เราต้องการเท่านั้น แต่ยังสามารถลดจำนวนรอบการเดินทางไปกลับ (round trip) ได้ด้วย query แบบนี้จำเป็นต้องให้เรานิยาม data type ต่างๆ ที่เรากำลังเข้าถึง การนิยาม type อย่างชัดเจนเป็นส่วนสำคัญของ GraphQL
ในการ implement GraphQL เราต้องมี resolver เพื่อจัดการ query resolver ของ GraphQL อยู่ฝั่งเซิร์ฟเวอร์และ map query ของ GraphQL เข้ากับการเรียกที่จะดึงข้อมูลจริงๆ ดังนั้นในกรณีของสถาปัตยกรรมไมโครเซอร์วิส เราจะต้องมี resolver ที่สามารถ map คำขอสำหรับ order ที่มี ID 123 ไปเป็นการเรียกที่เทียบเท่ากันไปยัง microservice
ด้วยวิธีนี้ เราสามารถใช้ GraphQL เพื่อ implement aggregating gateway หรือแม้แต่ BFF ได้ ประโยชน์ของ GraphQL คือเราสามารถเปลี่ยน aggregation และ filtering ที่เราต้องการได้ง่ายๆ แค่เปลี่ยน query จากฝั่งไคลเอนต์ โดยไม่ต้องเปลี่ยนแปลงอะไรที่ฝั่งเซิร์ฟเวอร์ของ GraphQL ตราบใดที่ type ของ GraphQL รองรับ query ที่เราต้องการทำ ถ้าเราไม่ต้องการเห็นชื่อคนขับใน query ตัวอย่างอีกต่อไป เราก็แค่ตัดมันออกจาก query เอง และมันก็จะไม่ถูกส่งมาอีก ในทางกลับกัน ถ้าเราต้องการเห็นจำนวนคะแนนที่เราได้รับจาก order นี้ สมมติว่าข้อมูลนี้มีอยู่ใน order type เราก็แค่เพิ่มมันเข้าไปใน query และข้อมูลนั้นก็จะถูกส่งกลับมา นี่เป็นข้อได้เปรียบที่สำคัญเหนือกว่า BFF implementation ที่ต้องการให้การเปลี่ยนแปลง aggregation logic ถูกนำไปใช้กับตัว BFF ด้วยเช่นกัน
ความยืดหยุ่นที่ GraphQL มอบให้กับอุปกรณ์ไคลเอนต์ในการเปลี่ยน query แบบ dynamic โดยไม่ต้องเปลี่ยนแปลงฝั่งเซิร์ฟเวอร์ หมายความว่ามีโอกาสน้อยลงที่ GraphQL server ของคุณจะกลายเป็นทรัพยากรที่ถูกแย่งชิงใช้ร่วมกัน อย่างที่เราคุยกันเรื่อง general-purpose aggregating gateway ถึงอย่างนั้น การเปลี่ยนแปลงฝั่งเซิร์ฟเวอร์ก็ยังจำเป็นอยู่ถ้าคุณต้องเปิด type ใหม่ หรือเพิ่ม field ให้กับ type ที่มีอยู่แล้ว ดังนั้นคุณอาจยังต้องการ GraphQL server backend หลายตัวที่จัดวางตามขอบเขตของทีม ดังนั้น GraphQL จึงกลายเป็นวิธีหนึ่งในการ implement BFF
ผมมีความกังวลเกี่ยวกับ GraphQL อยู่บ้าง ซึ่งผมได้อธิบายไว้อย่างละเอียดใน Chapter 5 ถึงอย่างนั้น มันก็เป็น solution ที่ดีที่รองรับการ query แบบ dynamic ให้เหมาะกับความต้องการของส่วนติดต่อผู้ใช้ประเภทต่างๆ