คุณกดปุ่ม 'สั่งซื้อ' มาแล้วนับครั้งไม่ถ้วน ภายในเวลาไม่ถึงหนึ่งวินาทีหลังจากนิ้วแตะจอ ข้อความชิ้นเล็ก ๆ ได้ออกเดินทางไปหาคอมพิวเตอร์อีกเครื่องหนึ่งที่คุณไม่เคยเห็น เครื่องนั้นตื่นขึ้นมาอ่าน ตรวจสอบ ตัดสินใจ แล้วส่งคำตอบกลับมา บทนี้เราจะติดตามการเดินทางนั้นทีละก้าว
ตอนที่ 1ทุกการกด มีคอมพิวเตอร์สองเครื่องเกี่ยวข้อง
ลองนึกถึงแอปสั่งกาแฟบนโทรศัพท์ เมื่อคุณกดสั่งลาเต้หนึ่งแก้ว โทรศัพท์ของคุณ ไม่ได้ ชงกาแฟ ไม่ได้รู้ว่าร้านเหลือนมกี่กล่อง และไม่ได้เป็นคนออกเลขคิว งานพวกนั้นเกิดขึ้นบนคอมพิวเตอร์อีกเครื่องหนึ่งของร้าน ซึ่งอาจตั้งอยู่ห่างออกไปหลายร้อยกิโลเมตร
โทรศัพท์ของคุณมีหน้าที่เดียว คือ ถาม แล้ว แสดงคำตอบ ส่วนคอมพิวเตอร์ของร้านมีหน้าที่ ฟังคำถาม ทำงาน และตอบ
หยุดคิดสักนิด
ถ้าโทรศัพท์ของลูกค้าทุกคนเก็บข้อมูลสต็อกของร้านไว้เองและตัดสินใจเองได้เลย จะเกิดปัญหาอะไรขึ้น?
สองบทบาทนี้มีชื่อเรียกที่คุณจะได้ยินตลอดทั้งเล่ม
- Clientไคลเอนต์ · ผู้ขอ
- โปรแกรมฝั่งที่เป็นคนเริ่มถาม เช่น เบราว์เซอร์บนคอมพิวเตอร์ หรือแอปบนโทรศัพท์ของคุณ มันส่งคำขอออกไปแล้วรอคำตอบ
- Serverเซิร์ฟเวอร์ · ผู้ให้บริการ
- โปรแกรมที่เปิดรอรับคำขอตลอดเวลา เมื่อมีคำขอเข้ามา มันจะทำงานตามที่ตั้งโปรแกรมไว้ แล้วส่งคำตอบกลับไป คำนี้ใช้เรียกทั้งตัวโปรแกรมและเครื่องที่รันโปรแกรมนั้น
ตอนที่ 2หน้าตาของ 'คำขอ' หนึ่งใบ
รูปแบบที่ตกลงกันนั้นมีชื่อว่า ไม่ว่าเบราว์เซอร์จะเป็นของค่ายไหน หรือเซิร์ฟเวอร์จะเขียนด้วยภาษาอะไร ถ้าทำตามกติกาเดียวกัน ก็คุยกันได้
เจาะลึก · สำหรับคนที่อยากรู้มากกว่านี้ก่อนใบสั่งจะออกเดินทาง เบราว์เซอร์ทำอะไรบ้าง?
coffee.example อยู่ที่ไหน มันจึงถามระบบ เพื่อแปลงชื่อเป็นหมายเลขที่อยู่ จากนั้นจึงเปิดการเชื่อมต่อกับเครื่องนั้น ถ้าที่อยู่ขึ้นต้นด้วย https:// ทั้งสองฝั่งจะตกลงกุญแจเข้ารหัสกันก่อน (กติกานี้ชื่อ TLS) เพื่อให้เครื่องกลางทางที่ส่งต่อข้อมูลอ่านใบสั่งข้างในไม่ออก ส่วนข้อความในบทนี้เขียนแบบ HTTP/1.1 ซึ่งคนอ่านง่ายที่สุด รุ่นใหม่อย่าง HTTP/2 และ HTTP/3 ห่อข้อมูลในรูปแบบที่กระชับกว่า แต่ความหมายยังเหมือนเดิม เรื่องการหาที่อยู่และการเข้ารหัสจะถูกเปิดดูเต็ม ๆ ในเล่ม 04- Requestรีเควสต์ · คำขอ
- ข้อความที่ Client ส่งไปหา Server เพื่อบอกว่าต้องการอะไร ประกอบด้วยการกระทำที่ต้องการ ที่อยู่ปลายทาง ข้อมูลกำกับ และเนื้อหา (ถ้ามี)
นี่คือหน้าตาจริงของ Request สั่งกาแฟหนึ่งแก้ว ตัวอักษรทั้งหมดนี้คือสิ่งที่เดินทางออกจากโทรศัพท์ของคุณจริง ๆ
POST /api/orders HTTP/1.1
Host: coffee.example
Content-Type: application/json
{
"drink": "latte",
"qty": 1,
"customerName": "มะลิ"
}- บรรทัดแรก บอกสามอย่าง:
POSTคือ ส่วน/api/ordersคือ 'ช่อง' ที่ต้องการติดต่อในเซิร์ฟเวอร์ และHTTP/1.1คือรุ่นของกติกา - บรรทัดถัดมา เรียกว่า เช่น
Hostบอกชื่อเว็บไซต์ปลายทางContent-Typeบอกว่าเนื้อหาข้างในเขียนแบบ JSON - หลังบรรทัดว่าง คือ Body หรือเนื้อหาของคำขอ ในที่นี้เขียนด้วย บอกว่าสั่งเมนูอะไร กี่แก้ว ชื่ออะไร
- Responseเรสพอนส์ · คำตอบ
- ข้อความที่ Server ส่งกลับไปหา Client หลังจากทำงานเสร็จ บอกผลลัพธ์ว่าสำเร็จหรือไม่ พร้อมข้อมูลที่เกี่ยวข้อง ทุก Request ที่ไปถึงเซิร์ฟเวอร์และได้รับการตอบ จะได้ Response กลับมาหนึ่งชุด
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/orders/ord_0042
{
"id": "ord_0042",
"drink": "latte",
"qty": 1,
"total": 65,
"status": "brewing"
}สังเกตบรรทัดแรก 201 Created ตัวเลขสามหลักนี้คือส่วนที่สำคัญที่สุดของคำตอบ เบราว์เซอร์และโปรแกรมเมอร์จะดูตัวเลขนี้ก่อนอ่านอย่างอื่น และสังเกตอีกอย่างว่า ราคารวม 65 บาทกับเลขออเดอร์ มาจากเซิร์ฟเวอร์ ไม่ได้คิดเองบนโทรศัพท์
ตอนที่ 3ตัวเลขสามหลักที่บอกผลลัพธ์
- HTTP Status Codeรหัสสถานะ
- ตัวเลขสามหลักในบรรทัดแรกของ Response ที่สรุปผลของคำขอแบบสั้นที่สุด ตัวเลขหลักแรกบอก 'กลุ่ม' ของผลลัพธ์ ส่วนสองหลักหลังบอกรายละเอียด
คุณไม่จำเป็นต้องจำรหัสทุกตัว แค่รู้ว่า หลักแรก หมายถึงอะไร ก็อ่านสถานการณ์ได้เกือบทั้งหมดแล้ว
- 2xx · สำเร็จ ได้ตามที่ขอ เช่น
200 OK(ได้ข้อมูลที่ขอ) และ201 Created(สร้างของใหม่สำเร็จ) - 3xx · ไปที่อื่น สิ่งที่ขอย้ายที่อยู่ไปแล้ว เบราว์เซอร์จะตามไปให้เอง เราจะพบกลุ่มนี้อีกครั้งในเล่ม 04
- 4xx · คำขอมีปัญหา เซิร์ฟเวอร์ทำงานปกติ แต่ทำตามคำขอนี้ไม่ได้ ฝั่งผู้ส่งต้องแก้คำขอ เช่น
400 Bad Requestและ404 Not Found - 5xx · เซิร์ฟเวอร์มีปัญหา คำขออาจถูกต้องทุกอย่าง แต่เซิร์ฟเวอร์เองทำงานผิดพลาด เช่น
500 Internal Server Error
หยุดคิดสักนิด
ถ้าลูกค้ากดสั่งกาแฟ 0 แก้ว เซิร์ฟเวอร์ควรตอบด้วยรหัสกลุ่มไหน?
ความเชื่อที่พบบ่อย
“เจอหน้า 404 แปลว่าเว็บไซต์ล่มแล้ว”
ลองจัดกลุ่ม · เหตุการณ์นี้ควรได้รหัสกลุ่มไหน?
ถูก 0/5
01เปิดหน้าแรกของเว็บไซต์ได้ตามปกติ
02พิมพ์ที่อยู่หน้าเว็บผิด จนไปเปิดหน้าที่ไม่มีอยู่จริง
03ยังไม่ได้ล็อกอิน แต่พยายามเปิดหน้าตั้งค่าบัญชี
04ฐานข้อมูลของร้านล่ม โค้ดบนเซิร์ฟเวอร์ทำงานต่อไม่ได้
05กดส่งข้อความตอนอยู่ในลิฟต์ แล้วสัญญาณหายพอดี
ตอนที่ 4ลงมือ: เปิดร้านกาแฟของคุณเอง
ถึงเวลาเห็นของจริงแล้ว ห้องทดลองด้านล่างแบ่งเป็นสามส่วน ซ้ายคือ เบราว์เซอร์ของลูกค้า ตรงกลางคือ เครือข่าย และขวาคือ ห้องเครื่องของเซิร์ฟเวอร์ ที่ลูกค้ามองไม่เห็น ลองทำภารกิจตามลำดับนี้
- เลือกสถานการณ์ ทุกอย่างปกติ แล้วกดสั่ง ดูไฟในห้องเครื่องติดทีละดวง และดูสต็อกลดลง
- เปลี่ยนเป็น ของหมด แล้วสั่งอีกครั้ง ดูว่าเซิร์ฟเวอร์หยุดที่ขั้นไหน และได้รหัสอะไร
- เปลี่ยนเป็น เซิร์ฟเวอร์พัง สังเกตว่าคำขอผ่านการตรวจทุกอย่าง แต่ไปพังตรงไหน
- เปลี่ยนเป็น เน็ตหลุด แล้วมองหาตัวเลขรหัสสถานะ คุณจะไม่เจอ ลองคิดว่าเพราะอะไร
- ภารกิจพิเศษ: กลับไปที่ ทุกอย่างปกติ แล้วลองลบชื่อออก หรือลดจำนวนเหลือ 0
LAB 02 — Request Processing Engine
ร้านกาแฟของเซิร์ฟเวอร์
สถานการณ์จำลอง · เลือกก่อนกดสั่ง
เซิร์ฟเวอร์ทำงานตามปกติ
Browser · ฝั่งลูกค้า
Server · coffee.example
IDLE · รอคำขอ
- รับคำขอ Receiveรอ
- ตรวจข้อมูล Validateรอ
- เช็กสต็อก Check stockรอ
- บันทึกและชงกาแฟ Save & brewรอ
- ส่งคำตอบกลับ Respondรอ
สต็อกในร้าน · เบราว์เซอร์มองไม่เห็นส่วนนี้
- ลาเต้6 แก้ว
- อเมริกาโน่8 แก้ว
- โกโก้4 แก้ว
POST /api/orders HTTP/1.1 Host: coffee.example Content-Type: application/json Accept: application/json { "drink": "latte", "qty": 1, "customerName": "มะลิ" }
// ยังไม่มี Response // กด 'สั่งเลย' เพื่อส่ง Request
เกิดอะไรขึ้น?
กด สั่งเลย แล้วดูซองสีน้ำเงินเดินทาง ซองนั้นคือ Request ที่เบราว์เซอร์ห่อข้อมูลคำสั่งซื้อส่งไปหาเซิร์ฟเวอร์ จากนั้นลองเปลี่ยนสถานการณ์จำลองด้านบน เพื่อดูว่าความล้มเหลวแต่ละแบบต่างกันอย่างไร หรือลองใส่จำนวนเป็น 0 หรือลบชื่อออก
ผลลัพธ์ 4 แบบ · ลองแล้ว 0/4
- 2xx
สำเร็จ
ได้สิ่งที่ขอ เช่น 201 Created
- 4xx
คำขอมีปัญหา
ฝั่งผู้ส่งต้องแก้คำขอ เช่น 400, 409
- 5xx
เซิร์ฟเวอร์มีปัญหา
ไม่ใช่ความผิดลูกค้า เช่น 500
- ไม่มีรหัส
ไปไม่ถึง / ไม่มีคำตอบ
ปัญหาที่ทางเดิน ไม่มี Response
ตอนที่ 5ล้มเหลวเหมือนกัน แต่ไม่เหมือนกันเลย
ถ้าคุณทำครบทุกภารกิจ คุณเพิ่งเห็นความล้มเหลวสี่แบบที่ผู้ใช้ทั่วไปมักเรียกรวมกันว่า 'เว็บมันเสีย' แต่สำหรับคนทำเว็บ ทั้งสี่แบบต่างกันมาก เพราะ คนที่ต้องลงมือแก้เป็นคนละคน
- 400 Bad Request ข้อมูลที่ส่งมาผิดรูปแบบ เช่น ไม่มีชื่อ หรือจำนวนเป็นศูนย์ คนที่ต้องแก้คือฝั่งผู้ส่ง
- 409 Conflict ข้อมูลถูกต้อง แต่ขัดกับสถานะตอนนี้ คือของหมด ในห้องทดลองเราใช้ 409 บางระบบเลือกใช้ 422 แทน ทั้งคู่อยู่ในกลุ่ม 4xx และเซิร์ฟเวอร์ไม่ได้พัง มันแค่ตอบได้ชัดว่าทำให้ไม่ได้
- 500 Internal Server Error คำขอไม่มีอะไรผิด แต่โค้ดของร้านเองเกิดข้อผิดพลาดกลางคัน คนที่ต้องแก้คือทีมของร้าน ลูกค้าทำได้แค่รอแล้วลองใหม่
- เน็ตหลุด ไม่มีรหัสใดเลย เพราะไม่มีคำตอบกลับมาให้อ่าน
ข้อควรรู้เพิ่มเติม: บางครั้งคุณอาจเห็นรหัส 502 หรือ 504 เวลาเว็บช้ามาก รหัสเหล่านี้มักมาจาก 'เครื่องกลางทาง' ที่ยืนรับคำขอแทนเซิร์ฟเวอร์หลัก เมื่อเครื่องกลางทางติดต่อเซิร์ฟเวอร์หลักไม่ได้ มันจะเขียน Response บอกเราเอง นั่นจึงยังนับว่ามีคำตอบ ต่างจากเน็ตหลุดที่ไม่มีใครตอบเลย
ความเชื่อที่พบบ่อย
“ถ้าแอปขึ้นว่า 'เชื่อมต่อไม่ได้' แปลว่าร้านไม่ได้รับออเดอร์ กดสั่งใหม่ได้เลย”
ลองฝึกมองแบบคนทำเว็บ อย่าดูแค่ว่า 'สำเร็จหรือล้มเหลว' แต่ถามต่อว่า ใครต้องทำอะไรต่อ อ่านแต่ละเหตุการณ์ของร้านกาแฟ แล้วเลือกว่าคนที่ต้องลงมือคือใคร
ลองจัดกลุ่ม
เหตุการณ์นี้ ใครต้องลงมือต่อ?
01แอปส่งออเดอร์ไปโดยไม่มีชื่อลูกค้า แล้วได้
400 Bad Request02สั่งโกโก้ 3 แก้ว แต่ร้านเหลือแค่ 2 แก้ว ได้
409 Conflict03โค้ดคิดราคาของร้านมีข้อผิดพลาด ทุกออเดอร์ได้
500 Internal Server Error04กดสั่งแล้วสัญญาณหายกลางทาง ไม่มีรหัสใดกลับมาเลย
เป้าหมาย: เลือกคำตอบให้ถูกครบทุกข้อ แล้วอ่านเหตุผลของแต่ละข้อ
หยุดคิดสักนิด
หน้าเว็บร้านกาแฟตรวจแล้วว่าต้องใส่ชื่อก่อนกดสั่ง แล้วทำไมเซิร์ฟเวอร์ยังต้องตรวจซ้ำอีก?
ตอนที่ 6ภาพเต็มของการกดหนึ่งครั้ง
ตอนนี้คุณเห็นแล้วว่าการกดปุ่มหนึ่งครั้งมีห้าจังหวะ: เบราว์เซอร์เขียนคำขอ ตามกติกา HTTP, คำขอเดินทาง ผ่านเครือข่าย, เซิร์ฟเวอร์ทำงาน ตรวจ ตัดสินใจ และบันทึก, เซิร์ฟเวอร์เขียนคำตอบ พร้อมรหัสสถานะ, แล้ว เบราว์เซอร์แสดงผล ให้คุณเห็น
ลองเดินตามออเดอร์ลาเต้ของมะลิอีกครั้ง คราวนี้ช้า ๆ ทีละก้าว สังเกตว่าแต่ละก้าวเกิดขึ้นบนเครื่องไหน และตรงไหนที่ทำให้คำตอบออกมาเป็น 400 หรือ 409 แทนที่จะเป็น 201
ติดตามทีละก้าว
การเดินทางของออเดอร์ ord_0042
- โทรศัพท์
- เครือข่าย
- เซิร์ฟเวอร์
โทรศัพท์เขียนคำขอ
มะลิกดสั่งลาเต้ 1 แก้ว แอปเขียน Request ตามกติกา HTTP: Method POST ไปที่ช่อง /api/orders พร้อม Body แบบ JSON ที่บอกเมนู จำนวน และชื่อ
เป้าหมาย: กด 'ก้าวถัดไป' จนถึงก้าวสุดท้าย
ในห้องทดลอง เซิร์ฟเวอร์ 'จำ' สต็อกไว้ในตัวเอง แต่ในระบบจริง ถ้าเซิร์ฟเวอร์ปิดเครื่องหรือรีสตาร์ต ความจำนั้นจะหายไปทันที เซิร์ฟเวอร์จริงจึงฝากข้อมูลสำคัญไว้ที่อีกที่หนึ่งซึ่งออกแบบมาเพื่อจำโดยเฉพาะ สิ่งนั้นคือ ฐานข้อมูล หัวใจของเล่ม 03
SYSTEM SUMMARY
สรุปบทนี้
- 01Client คือฝั่งที่ถาม Server คือฝั่งที่ฟัง ทำงาน และตอบ โค้ดที่ทำงานบนเซิร์ฟเวอร์เรียกว่า Backend
- 02Request และ Response คือข้อความที่เขียนตามกติกา HTTP มีบรรทัดแรก Header และ Body
- 03HTTP Status Code หลักแรกบอกกลุ่ม: 2xx สำเร็จ, 4xx คำขอมีปัญหา, 5xx เซิร์ฟเวอร์มีปัญหา
- 04เน็ตหลุดไม่มีรหัสสถานะ เพราะไม่มี Response และฝั่งเบราว์เซอร์ไม่รู้ว่าคำขอไปถึงหรือไม่
- 05ข้อมูลสำคัญอย่างราคาและสต็อกต้องตัดสินที่เซิร์ฟเวอร์ ไม่ใช่บนเครื่องของลูกค้า
ท้ายบท
เช็กความเข้าใจ
ตอบแล้ว 0/4
ไม่มีคะแนนเก็บ ไม่มีใครเห็นคำตอบนอกจากคุณ ทุกตัวเลือกมีเหตุผลอธิบาย ทั้งข้อที่ถูกและข้อที่ผิด
ขั้นสุดท้าย ลองอธิบายด้วยคำพูดของคุณเอง นี่ไม่ใช่ข้อสอบ ระบบไม่ได้อ่านหรือให้คะแนนคำตอบ แต่การได้เรียบเรียงเป็นคำพูดของตัวเอง คือวิธีที่ดีที่สุดในการรู้ว่าเราเข้าใจจริงหรือยัง
อธิบายด้วยคำพูดของคุณเอง
ข้อความนี้อยู่แค่ในหน้าจอของคุณ ไม่ถูกส่งหรือบันทึกไว้ที่ไหน และระบบไม่ได้ให้คะแนน
เส้นทางการเรียนรู้
0/4
- แยกว่าความล้มเหลวแต่ละแบบ ใครต้องลงมือแก้ (ยังไม่ได้ทำ)ภาพ 1.2: เลือกคำตอบให้ถูกครบทุกข้อ
- ติดตามออเดอร์ลาเต้หนึ่งแก้วครบทุกก้าว (ยังไม่ได้ทำ)ภาพ 1.3: กด 'ก้าวถัดไป' จนถึงก้าวสุดท้าย
- ตอบแบบทดสอบท้ายบทครบทุกข้อ (ยังไม่ได้ทำ)ตอบครบทุกข้อ ผิดได้ ไม่มีผลกับการติ๊ก
- อธิบายด้วยคำพูดของตัวเอง (ยังไม่ได้ทำ)เขียนอย่างน้อย 30 ตัวอักษร แล้วกด 'เทียบกับคำอธิบายตัวอย่าง'
รายการนี้บันทึกสิ่งที่คุณได้ลงมือทำในเบราว์เซอร์นี้ ไม่ใช่ใบรับรองว่าเข้าใจแล้ว วิธีวัดที่ดีที่สุดคือลองอธิบายให้คนอื่นฟัง ล้างบันทึกได้ที่ Machine Lens แท็บ DATABASE