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

Request Lifecycle

ตอนนี้คุณรู้แล้วว่า schema และ query คืออะไร พื้นฐานข้อสุดท้ายคือการเข้าใจว่าเกิดอะไรขึ้น ระหว่าง การส่ง query กับการรับ response GraphQL server ประมวลผลทุก request ในสามเฟสที่เรียงลำดับกัน: parse, validate และ execute การรู้เฟสเหล่านี้บอกคุณได้อย่างแม่นยำว่า request จะล้มเหลวที่ไหนและทำไม

sequenceDiagram
  participant C as Client
  participant P as Parse
  participant V as Validate
  participant E as Execute (resolvers)
  participant D as Data sources
  C->>P: query text
  P->>V: AST (grammar OK)
  Note over V: check AST against the schema
  V--xC: errors array if a field is invalid (no resolver runs)
  V->>E: validated AST
  E->>D: call resolvers, walk the query
  D-->>E: field values
  E-->>C: response shaped like the query
ทุก request ของ GraphQL ไหลผ่าน parse แล้ว validate แล้วจึง execute

server รับ query มาเป็นข้อความธรรมดา แล้วแปลงเป็น tree ที่มีโครงสร้างเรียกว่า Abstract Syntax Tree (AST) เฟสนี้ตรวจเฉพาะ ไวยากรณ์ ว่าวงเล็บปีกกาสมดุลไหม syntax ถูกรูปแบบหรือเปล่า วงเล็บปิดที่หายไปหรือ comma หลงทางจะล้มเหลวตรงนี้ ตั้งแต่ก่อนไปดู schema ด้วยซ้ำ

ตอนนี้ server เทียบ AST กับ schema นี่คือจุดที่ type system ทำงานคุ้มค่า ตัว validator ยืนยันว่าทุก field ที่คุณเลือกมีอยู่จริงบน type นั้น argument มี type ถูกต้อง คุณไม่ได้ขอ scalar field พร้อม sub-selection และกฎอีกหลายสิบข้อ ถ้า validation ไม่ผ่าน server จะปฏิเสธ request แล้วคืน array ของ errors และที่สำคัญคือ ไม่มี resolver ตัวไหนรันเลย query ไม่เคยแตะข้อมูลหรือ business logic ของคุณ

เมื่อ query ผ่าน parse และ validate แล้ว server จะ execute โดยเดินไปตาม AST และเรียก resolver ของแต่ละ field การ execute เริ่มที่ root type (Query, Mutation หรือ Subscription) แล้วไล่ลงทีละ field resolver แต่ละตัวคืนค่ากลับมา ถ้าค่านั้นเป็น object type engine จะ recurse เข้าไปใน sub-field ที่ถูกเลือกแล้วเรียก resolver ต่อไปตามลำดับ ค่าที่คืนมาทั้งหมดจะถูกประกอบเป็น response ที่มีรูปร่างสะท้อน query

วิธีที่ดีที่สุดในการเห็นความต่างระหว่าง validation กับ execution คือดูตอน validation จับ error ตัวรันด้านล่างส่ง query ที่ขอ field ชื่อ colour ซึ่งไม่มีอยู่บน type Book กด Run ดู schema ถูกต้องและ resolver พร้อมแล้ว แต่ request ไปไม่ถึง resolver เลย สิ่งที่ได้กลับมาคือ array ของ errors ที่อธิบายปัญหา

JavaScript

อ่านผลลัพธ์ให้ละเอียด ไม่มี data ของ book แต่ได้ array ของ errors ที่บอกว่า colour query บน type Book ไม่ได้ พร้อมบรรทัดและคอลัมน์ที่ปรากฏ นี่คือเฟส validate ที่กำลังทำหน้าที่ ลองแก้ query เปลี่ยน colour เป็น year แล้วรันอีกครั้ง จะเห็น request แล่นผ่าน validation เข้าสู่ execution และคืนข้อมูลจริง

ข้อดีข้อแลกเปลี่ยน
parse และ validate เกิดก่อน execution — error ชัดเจนก่อนถึง resolvervalidation overhead ทุก request (แก้ด้วย persisted query)
execution pipeline ชัดเจน — debug ได้ตามขั้นตอนresolver ที่ขนานกันอาจทำให้ trace ยาก
middleware/plugin แต่ละ phase แยกกันerror ใน resolver หนึ่งไม่หยุด resolver อื่น — partial result
context injection ทำให้แชร์ auth, db connection ข้าม resolverexecution order ไม่ guaranteed สำหรับ parallel field

Business Logic ใน Resolver โดยตรง อาการ:

  • resolver มี SQL query, validation, auth check, และ business rule ปะปนกัน
  • test ยาก เพราะต้อง mock database ใน unit test ของ resolver
  • แยก data fetching ออกจาก business logic — resolver ควรบาง

ไม่มี Error Boundary ใน Resolver อาการ:

  • resolver throw unhandled error ทำให้ทั้ง query fail
  • client ไม่รู้ว่า field ไหน fail และ field ไหนสำเร็จ
  • handle error ใน resolver อย่างตั้งใจ — return null หรือ throw GraphQL error

💡 ตัวอย่างจากของจริง

Apollo Server:

  • lifecycle plugin ช่วย track ทุก phase: parse, validate, execute
  • ใช้ใน production monitoring ที่ Apollo Studio

Yoga (GraphQL Yoga):

  • envelop plugin system ที่ intercept ทุก phase ของ lifecycle
  • ใช้สำหรับ tracing, auth, rate limiting ใน pipeline
สามเฟสของการจัดการ request ของ GraphQL เรียงตามลำดับคืออะไร?
ในเฟสใดที่ query ถูกตรวจสอบเทียบกับ schema เพื่อหา field ที่ไม่รู้จักและ type ของ argument ที่ผิด?
หาก query ขอ field ที่ไม่มีอยู่บน type จะเกิดอะไรขึ้น?
เฟสใดที่เรียก resolver จริง ๆ และแตะแหล่งข้อมูลของคุณ?