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
1. Parse
หัวข้อที่มีชื่อว่า “1. Parse”server รับ query มาเป็นข้อความธรรมดา แล้วแปลงเป็น tree ที่มีโครงสร้างเรียกว่า Abstract Syntax Tree (AST) เฟสนี้ตรวจเฉพาะ ไวยากรณ์ ว่าวงเล็บปีกกาสมดุลไหม syntax ถูกรูปแบบหรือเปล่า วงเล็บปิดที่หายไปหรือ comma หลงทางจะล้มเหลวตรงนี้ ตั้งแต่ก่อนไปดู schema ด้วยซ้ำ
2. Validate
หัวข้อที่มีชื่อว่า “2. Validate”ตอนนี้ server เทียบ AST กับ schema นี่คือจุดที่ type system ทำงานคุ้มค่า ตัว validator ยืนยันว่าทุก field ที่คุณเลือกมีอยู่จริงบน type นั้น argument มี type ถูกต้อง คุณไม่ได้ขอ scalar field พร้อม sub-selection และกฎอีกหลายสิบข้อ ถ้า validation ไม่ผ่าน server จะปฏิเสธ request แล้วคืน array ของ errors และที่สำคัญคือ ไม่มี resolver ตัวไหนรันเลย query ไม่เคยแตะข้อมูลหรือ business logic ของคุณ
3. Execute
หัวข้อที่มีชื่อว่า “3. Execute”เมื่อ 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 ปฏิเสธ field ที่ไม่ถูกต้อง
หัวข้อที่มีชื่อว่า “validation ปฏิเสธ field ที่ไม่ถูกต้อง”วิธีที่ดีที่สุดในการเห็นความต่างระหว่าง validation กับ execution คือดูตอน validation จับ error ตัวรันด้านล่างส่ง query ที่ขอ field ชื่อ colour ซึ่งไม่มีอยู่บน type Book กด Run ดู schema ถูกต้องและ resolver พร้อมแล้ว แต่ request ไปไม่ถึง resolver เลย สิ่งที่ได้กลับมาคือ array ของ errors ที่อธิบายปัญหา
อ่านผลลัพธ์ให้ละเอียด ไม่มี data ของ book แต่ได้ array ของ errors ที่บอกว่า colour query บน type Book ไม่ได้ พร้อมบรรทัดและคอลัมน์ที่ปรากฏ นี่คือเฟส validate ที่กำลังทำหน้าที่ ลองแก้ query เปลี่ยน colour เป็น year แล้วรันอีกครั้ง จะเห็น request แล่นผ่าน validation เข้าสู่ execution และคืนข้อมูลจริง
| ข้อดี | ข้อแลกเปลี่ยน |
|---|---|
| parse และ validate เกิดก่อน execution — error ชัดเจนก่อนถึง resolver | validation overhead ทุก request (แก้ด้วย persisted query) |
| execution pipeline ชัดเจน — debug ได้ตามขั้นตอน | resolver ที่ขนานกันอาจทำให้ trace ยาก |
| middleware/plugin แต่ละ phase แยกกัน | error ใน resolver หนึ่งไม่หยุด resolver อื่น — partial result |
| context injection ทำให้แชร์ auth, db connection ข้าม resolver | execution 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