🔵 Node.js

เจาะลึก Express Middleware คืออะไร? พร้อมวิธีใช้งาน req, res, next และ Built-in Middlewares

9 นาที 24 views บันทึกเป็น PDF
เจาะลึก Express Middleware คืออะไร? พร้อมวิธีใช้งาน req, res, next และ Built-in Middlewares

มือใหม่หัดใช้ Node.js ต้องรู้! ทำความเข้าใจการทำงานของ Middleware ใน Express.js ตั้งแต่โครงสร้าง req, res, next ไปจนถึงการใช้ express.json() เพื่อจัดการข้อมูล

ทำความรู้จักกับ Middleware หัวใจสำคัญของ Express

เวลาที่เราเขียนเว็บด้วย Node.js เรามักจะใช้เฟรมเวิร์ก (โครงสร้างโปรแกรมสำเร็จรูป) ที่ชื่อว่า Express เพื่อช่วยจัดการงานต่างๆ ให้ง่ายขึ้น สิ่งหนึ่งที่มือใหม่ต้องเจอและต้องทำความเข้าใจให้แม่นคือ Middleware (ฟังก์ชันตัวกลางที่คอยดักจับและจัดการคำขอ) เปรียบเสมือนด่านตรวจในสถานีขนส่งที่คอยตรวจสอบคนเข้าออกก่อนจะถึงที่หมายปลายทาง

ลองจินตนาการว่าคุณเป็นพนักงานต้อนรับในโรงแรม เมื่อมีแขกเดินเข้ามา คุณต้องทำหน้าที่ตรวจสอบเอกสาร ตรวจสอบว่าจองห้องไว้ไหม และอาจจะช่วยถือกระเป๋าไปส่งที่ห้อง Middleware ก็ทำงานแบบเดียวกัน คือคอยดักคำขอจากผู้ใช้งาน (Request) เพื่อตรวจสอบข้อมูลหรือแก้ไขข้อมูล ก่อนที่จะส่งต่อไปยังขั้นตอนถัดไปในระบบของเรา

ถ้าไม่มี Middleware เราก็ต้องเขียนโค้ดเช็คทุกอย่างซ้ำๆ ในทุกหน้าของเว็บไซต์ ซึ่งจะทำให้โค้ดของเรายาวและจัดการยากมาก การใช้ระบบนี้จะช่วยให้เราแยกส่วนการทำงานออกเป็นชิ้นๆ เหมือนจิ๊กซอว์ ทำให้โปรแกรมเมอร์อย่างเราดูแลและแก้ไขบั๊ก (ข้อผิดพลาดในโปรแกรม) ได้ง่ายขึ้นมากในระยะยาว

โครงสร้างของ Middleware Function (req, res, next)

หัวใจหลักของ Middleware คือฟังก์ชันที่มีพารามิเตอร์ (ตัวแปรที่รับค่าเข้ามา) 3 ตัวหลักเสมอ ได้แก่ req, res และ next ซึ่งแต่ละตัวทำหน้าที่แตกต่างกันอย่างชัดเจน ถ้าขาดตัวใดตัวหนึ่งไป ระบบของเราอาจจะค้างหรือทำงานต่อไม่ได้จนผู้ใช้งานเข้าเว็บไม่ได้เลย

ตัวแรกคือ req (Request) คือข้อมูลที่ผู้ใช้งานส่งเข้ามาหาเซิร์ฟเวอร์ เช่น ข้อมูลที่กรอกในฟอร์ม หรือที่อยู่ของหน้าเว็บที่เขาเรียกดู ตัวที่สองคือ res (Response) คือเครื่องมือที่เราใช้ส่งข้อมูลกลับไปหาผู้ใช้งาน เช่น ส่งหน้าเว็บเพจหรือส่งข้อมูลแบบ JSON (รูปแบบข้อมูลที่คอมพิวเตอร์อ่านง่าย) กลับไป

ตัวสุดท้ายคือ next ซึ่งเป็นฟังก์ชันที่สำคัญมาก มันทำหน้าที่บอก Express ว่า "งานของฟังก์ชันนี้เสร็จแล้ว ให้ไปทำงานในขั้นตอนถัดไปได้เลย" ถ้าเราไม่เรียกใช้ next() โปรแกรมก็จะหยุดนิ่งอยู่ที่ตรงนั้นและไม่ยอมส่งคำตอบกลับไปหาผู้ใช้งาน ทำให้หน้าเว็บหมุนค้างตลอดเวลา

// ตัวอย่าง Middleware พื้นฐาน
const myMiddleware = (req, res, next) => {
  console.log('มีคนเรียกใช้งานหน้าเว็บแล้ว');
  next(); // ส่งต่อไปยังขั้นตอนถัดไป
};

app.use(myMiddleware); // นำ Middleware ไปใช้งานกับทุกๆ คำขอ

ในตัวอย่างนี้ เราสร้างฟังก์ชันชื่อ myMiddleware ขึ้นมาเพื่อพิมพ์ข้อความลงใน Terminal (หน้าจอแสดงผลคำสั่งของโปรแกรมเมอร์) เมื่อมีการเรียกใช้งานหน้าเว็บ คำสั่ง next() จะเป็นตัวปลดล็อกให้ Express ทำงานในส่วนถัดไปได้ทันที

ผลลัพธ์ที่ควรเห็นคือ เมื่อคุณเปิดเบราว์เซอร์เข้าหน้าเว็บ ใน Terminal ของคุณจะปรากฏข้อความว่า "มีคนเรียกใช้งานหน้าเว็บแล้ว" และหน้าเว็บจะโหลดข้อมูลขึ้นมาตามปกติ เพราะเราได้ส่งสัญญาณผ่าน next() ไปแล้วนั่นเอง

Built-in Middlewares ตัวช่วยที่มาพร้อมกับ Express

Express เตรียมฟังก์ชันสำเร็จรูปที่เรียกว่า Built-in Middlewares (ตัวกลางที่ Express มีมาให้ในตัว) มาให้เราใช้งานได้ทันทีโดยไม่ต้องติดตั้งอะไรเพิ่ม ซึ่งส่วนใหญ่มักใช้จัดการกับข้อมูลที่ผู้ใช้งานส่งเข้ามาผ่านฟอร์มหรือผ่าน API (ช่องทางเชื่อมต่อระหว่างโปรแกรม) เพื่อให้เรานำไปใช้งานต่อได้ง่ายขึ้น

ตัวที่ใช้บ่อยที่สุดคือ express.json() ซึ่งทำหน้าที่แปลงข้อมูลที่ส่งมาเป็นรูปแบบ JSON ให้กลายเป็น Object (กลุ่มข้อมูลที่มีคุณสมบัติเฉพาะ) ใน JavaScript ทำให้เราดึงค่าต่างๆ มาใช้ได้ทันทีโดยไม่ต้องไปแกะรหัสเองให้ยุ่งยาก เป็นเครื่องมือพื้นฐานที่โปรแกรมเมอร์ Backend (ระบบหลังบ้าน) ทุกคนต้องใช้

อีกตัวคือ express.urlencoded() ซึ่งทำหน้าที่คล้ายกันแต่ใช้สำหรับข้อมูลที่ส่งมาจากฟอร์ม HTML แบบดั้งเดิม ถ้าเราไม่ใส่สองตัวนี้ ข้อมูลที่ส่งเข้ามาจะกลายเป็นค่าว่างหรือค่าที่อ่านไม่รู้เรื่อง ทำให้โปรแกรมของเราทำงานผิดพลาดได้ง่ายมากในการรับส่งข้อมูลจริง

// การตั้งค่า Middleware สำคัญ
app.use(express.json()); // รับข้อมูล JSON
app.use(express.urlencoded({ extended: true })); // รับข้อมูลจากฟอร์ม

โค้ดด้านบนคือการบอก Express ว่าให้เตรียมรับข้อมูลสองรูปแบบนี้ไว้เสมอ โดย extended: true เป็นการตั้งค่าให้ระบบรองรับข้อมูลที่ซับซ้อนขึ้นได้ดีขึ้น หากขาดบรรทัดเหล่านี้ไป เมื่อเราลองส่งข้อมูลผ่านเครื่องมือทดสอบ API อย่าง Postman ข้อมูลที่เซิร์ฟเวอร์ได้รับจะเป็น undefined (ค่าที่ยังไม่ได้กำหนด) ทันที

ผลลัพธ์คือเมื่อเราส่งข้อมูลในรูปแบบ JSON ผ่านคำสั่ง POST (คำสั่งส่งข้อมูลเข้าเซิร์ฟเวอร์) เข้ามา ระบบจะสามารถอ่านค่าใน req.body ได้อย่างถูกต้อง ช่วยให้เราจัดการข้อมูลที่ผู้ใช้กรอกเข้ามาได้อย่างแม่นยำและปลอดภัย

Custom Middlewares สร้างฟังก์ชันจัดการงานเฉพาะทาง

นอกจากของที่มีให้แล้ว บางครั้งเราก็ต้องเขียน Custom Middlewares (ฟังก์ชันตัวกลางที่เราสร้างขึ้นเอง) เพื่อทำงานเฉพาะอย่าง เช่น การตรวจสอบว่าผู้ใช้งานล็อกอินหรือยัง หรือการบันทึกประวัติการใช้งาน (Logging) เพื่อดูว่ามีใครเข้ามาทำอะไรในระบบบ้างในช่วงเวลาต่างๆ

การสร้างฟังก์ชันเหล่านี้ช่วยให้เราทำ Code Reuse (การนำโค้ดกลับมาใช้ซ้ำ) ได้ดีมาก แทนที่จะเขียนโค้ดเช็คสิทธิ์ในทุกๆ หน้า เราก็แค่สร้าง Middleware ขึ้นมาตัวหนึ่งแล้วแปะไว้หน้าเส้นทาง (Route) ที่ต้องการป้องกัน ใครที่ไม่มีสิทธิ์ผ่านด่านนี้ ก็จะไม่สามารถเข้าไปถึงข้อมูลสำคัญได้เลย

จุดที่มือใหม่มักพลาดคือการลืมใส่ next() ในกรณีที่เงื่อนไขผ่าน หรือลืมส่ง res.status().send() ในกรณีที่เงื่อนไขไม่ผ่าน ทำให้ระบบค้างหรือทำงานผิดปกติ หากคุณกำลังหัดเขียน ให้ลองสร้างฟังก์ชันเช็คเวลาเข้าใช้งานดูก่อน แล้วค่อยขยับไปทำระบบตรวจสอบสิทธิ์ที่ซับซ้อนขึ้นในอนาคต

// ตัวอย่าง Middleware เช็คสิทธิ์
const checkAuth = (req, res, next) => {
  const token = req.headers['authorization'];
  if (token === 'secret-key') {
    next(); // ผ่านไปได้
  } else {
    res.status(403).send('ไม่มีสิทธิ์เข้าถึง'); // ปฏิเสธการเข้าถึง
  }
};

ในตัวอย่างนี้ เราตรวจสอบค่าใน headers (ส่วนหัวของคำขอที่เก็บข้อมูลสำคัญ) ว่าตรงกับค่าที่กำหนดไว้ไหม ถ้าตรงก็ให้ next() ไปต่อ แต่ถ้าไม่ตรงเราจะใช้ res.status(403) เพื่อบอกว่าห้ามเข้าถึง และส่งข้อความแจ้งเตือนกลับไปแทน

ผลลัพธ์คือหากคุณส่งคำขอโดยไม่มีค่าที่ถูกต้อง ระบบจะตอบกลับด้วยสถานะ 403 และข้อความ "ไม่มีสิทธิ์เข้าถึง" ทันที ทำให้เว็บไซต์ของคุณมีความปลอดภัยมากขึ้นและป้องกันการเข้าถึงข้อมูลจากผู้ที่ไม่เกี่ยวข้องได้จริง

ข้อควรระวังและแนวปฏิบัติที่ดี

ลำดับการวาง Middleware มีผลมากใน Express เพราะมันทำงานจากบนลงล่างตามลำดับที่เราเขียนไว้ ถ้าเราวาง app.use() ไว้ผิดที่ อาจทำให้คำขอที่ควรจะได้รับข้อมูลกลับไปถูกดักไว้ก่อน หรือทำงานข้ามขั้นตอนที่สำคัญไป ส่งผลให้เกิดบั๊กที่หาจุดแก้ได้ยากมาก

คำแนะนำสำหรับมือใหม่คือ ให้วาง Built-in Middlewares ไว้บนสุดเสมอ เพื่อให้แน่ใจว่าข้อมูลที่เข้ามาจะถูกแปลงพร้อมใช้งานก่อนจะเข้าสู่ฟังก์ชันอื่นๆ และควรแยก Custom Middlewares ออกเป็นไฟล์ต่างหากเมื่อโปรเจกต์เริ่มใหญ่ขึ้น เพื่อให้โค้ดอ่านง่ายและจัดการได้เป็นระเบียบ

ระวังเรื่อง Middleware ที่ทำงานหนักเกินไป เช่น การเขียนไฟล์ลงฐานข้อมูลขนาดใหญ่ในทุกๆ คำขอ เพราะจะทำให้เซิร์ฟเวอร์ช้าลงอย่างเห็นได้ชัด ให้เน้นทำเฉพาะงานที่จำเป็นจริงๆ หรือถ้าเป็นงานหนักให้ส่งไปทำในกระบวนการเบื้องหลังแทน เพื่อรักษาประสิทธิภาพของเว็บไซต์ให้ตอบสนองได้รวดเร็วอยู่เสมอ

สรุป: นำไปใช้ในโปรเจกต์จริงของคุณ

การเข้าใจ Middleware ไม่ใช่แค่การจำคำสั่ง แต่คือการเข้าใจกระแสการไหลของข้อมูลในระบบ Express ตั้งแต่ต้นจนจบ ลองนำความรู้นี้ไปใช้กับโปรเจกต์แรกของคุณ เช่น การทำระบบบันทึกเวลาที่คนเข้ามาใช้งาน หรือระบบตรวจสอบรหัสผ่านง่ายๆ ก่อนจะเข้าถึงหน้าข้อมูลส่วนตัว

หากคุณเจอข้อผิดพลาดที่หน้าเว็บหมุนค้าง ให้กลับไปเช็คที่ Middleware ของคุณก่อนเสมอว่ามีการเรียกใช้ next() หรือการส่ง res กลับไปครบถ้วนหรือไม่ นี่คือจุดที่โปรแกรมเมอร์มือใหม่ทุกคนต้องผ่านไปให้ได้ด้วยการฝึกฝนและทำความเข้าใจลำดับการทำงานของมัน

การฝึกเขียน Middleware ให้คล่องจะช่วยให้คุณก้าวเข้าสู่การเป็นโปรแกรมเมอร์ Backend ที่เก่งขึ้นอย่างรวดเร็ว เพราะคุณจะสามารถควบคุมการทำงานของเซิร์ฟเวอร์ได้อย่างอิสระและมั่นใจ ขอให้สนุกกับการเขียนโค้ดและสร้างสรรค์ระบบเว็บที่ยอดเยี่ยมด้วยความเข้าใจที่ถูกต้องครับ

แชร์บทความ

Facebook X LINE

บทความที่เกี่ยวข้อง

คู่มือการทำ Production Deployment: รันโปรเจกต์ด้วย PM2 และ Docker ให้เสถียรเหมือนมือโปร
Node.js

คู่มือการทำ Production Deployment: รันโปรเจกต์ด้วย PM2 และ Docker ให้เสถียรเหมือนมือโปร

เรียนรู้วิธีนำโปรเจกต์ขึ้นเซิร์ฟเวอร์จริงให้รันได้ 24 ชั่วโมงด้วย PM2 และใช้ Docker ช่วยคุมสภาพแวดล้อมให้เหมือนกันทุกเครื่อง ลดปัญหาโค้ดพังเมื่อย้ายที่

1 week ago 11 นาที
15 views
เปลี่ยนโปรเจกต์ Node.js เป็น TypeScript: วิธีตั้งค่าและใช้งานสำหรับมือใหม่
Node.js

เปลี่ยนโปรเจกต์ Node.js เป็น TypeScript: วิธีตั้งค่าและใช้งานสำหรับมือใหม่

อยากเปลี่ยนจาก Node.js มาใช้ TypeScript แต่ไม่รู้เริ่มยังไง? บทความนี้สอนตั้งค่า tsconfig.json, การรันด้วย tsx และการทำ Type Checking ให้ Express แบบเข้าใจง่าย

1 week ago 9 นาที
12 views
สอนเขียน Automated Testing ด้วย Jest และ Supertest สำหรับมือใหม่
Node.js

สอนเขียน Automated Testing ด้วย Jest และ Supertest สำหรับมือใหม่

เลิกทดสอบโค้ดด้วยมือแบบเดิม ๆ มาหัดเขียน Automated Testing ด้วย Jest และ Supertest เพื่อเช็กฟังก์ชันและ API ให้ทำงานถูกต้องแม่นยำ ลดบั๊กกวนใจ

1 week ago 9 นาที
15 views