ข้ามไปยังเนื้อหา

Pagination & Relationships

GraphQL schema ไม่ใช่รายการ record แบน ๆ แต่เป็น กราฟ จุดมุ่งหมายทั้งหมดของระบบ type คือให้ field บน type หนึ่งคืนค่าเป็น type อื่น ได้ query เดียวจึงเดินจาก user ไปยัง post ของ user แล้วต่อไปยัง comment ของแต่ละ post ได้ในรอบเดียว ไม่ต้องมี round trip รอบที่สอง

คำถามสองข้อตัดสินว่ากราฟนั้นใช้งานได้ดีแค่ไหน — type ต่าง ๆ เชื่อมโยง กันอย่างไร และคุณจะเปิดดู รายการยาว ๆ ที่การเชื่อมโยงเหล่านั้นสร้างขึ้นทีละหน้าได้อย่างไร โมดูลนี้ตอบทั้งสองข้อ เริ่มจาก relationship — เส้นเชื่อม (edge) ของกราฟ — จากนั้นดูสองวิธีหลักของ pagination และปิดท้ายด้วยกับดักด้านประสิทธิภาพที่ดักเกือบทุกคนตอน resolve รายการข้อมูลที่เกี่ยวข้องกันครั้งแรก

จบโมดูลนี้คุณจะสร้างโมเดลการเชื่อมต่อระหว่าง type ได้ เลือกสไตล์ pagination อย่างตั้งใจแทนที่จะเลือกตามความเคยชิน และรักษา query ที่มี relationship เยอะ ๆ ให้ยังเร็วอยู่ ทั้งห้าบทเรียนคือ

  1. Pagination & Relationships (คุณอยู่ที่นี่) — ภาพรวมและ query ที่ซ้อนกัน
  2. Relationships — one-to-many และ many-to-many ในรูปของ field ที่คืนค่าเป็น type และ list
  3. Offset Pagination — การเปิดทีละหน้าแบบ limit/offset อย่างง่าย และจุดที่วิธีนี้พัง
  4. Relay Connections — สเปก cursor connection ได้แก่ edges, node, cursor, pageInfo
  5. N+1 and DataLoader — ทำไม resolver ของ list จึงยิง query หนึ่งครั้งต่อหนึ่ง item และ batching แก้ปัญหานี้อย่างไร

เนื้อหานี้ต่อยอดโดยตรงจากสิ่งที่คุณรู้อยู่แล้วเรื่องระบบ typeและ resolver — relationship เป็นเพียง field ที่มี type เป็น object type อีกตัว และ pagination ก็เป็นเพียง argument บน field ที่เป็น list

flowchart LR
  Author["type Author"]
  Post["type Post"]
  Author -->|"posts(first): [Post!]! — needs paging"| Post
  Post -->|"author: Author! — single link"| Author
relationship คือ field บน type หนึ่งที่มีค่าเป็น type อีกตัวหนึ่ง

อ่านไดอะแกรม: Author มี field posts ที่คืน list ของ Post และแต่ละ Post มี field author ชี้กลับมา

pagination จะไปอยู่ที่ฝั่ง list เสมอ — posts แทบไม่เคยคืน post ทุกอัน ออกมา จึงรับ argument อย่าง first หรือ limit เพื่อขอดูเป็นช่วง ๆ ส่วนการเชื่อมแบบเดี่ยว (author) ไม่ต้องการ pagination เพราะคืนค่าได้มากที่สุดเพียงค่าเดียว

ตัวอย่างด้านล่างนิยาม type Author กับ Post เชื่อมทั้งสองทิศทาง แล้วรัน query หนึ่งที่ข้าม relationship — ดึง author พร้อม post ของ author นั้นเป็นช่วง ๆ กดปุ่ม Run เพื่อรันด้วย GraphQL engine ตัวจริง

JavaScript

ดูที่ผลลัพธ์ เราเริ่มที่ author หนึ่งคน ก้าวเข้าไปใน list ของ posts แบบ เป็นช่วง (ได้มาสองอัน เพราะ limit: 2) แล้วจากแต่ละ post ก้าวกลับเข้าไปที่ author ของ post นั้น รวมเป็นหนึ่ง request สามก้าวข้ามกราฟ ส่วนที่เหลือของโมดูลนี้ว่าด้วยการทำแต่ละก้าวให้ดี — สร้างโมเดลการเชื่อมโยงให้สะอาด และเปิดดู list ทีละหน้าอย่างคาดเดาได้

ใน GraphQL relationship ระหว่างสอง type คืออะไรอย่างเป็นรูปธรรม?
field ใดต่อไปนี้น่าจะต้องการ argument สำหรับ pagination มากที่สุด?
query เดียวของ GraphQL ทำให้ client ทำอะไรได้ข้าม relationship?