สอนทำเว็บไซต์ด้วย Node.js, Express และ MongoDB ตอนที่ 8 - Express Generator / Middleware
สวัสดีครับ มาต่อกันที่ตอนที่ 8 กันนะครับ หลังจากหายไปนานเป็นอาทิตย์เลย พอดีช่วงนี้งานยุ่งมากๆ ตอนก่อนหน้านี้เราได้รู้จักกับ MongoDB กันไปแล้ว วันนี้เราจะมาเขียน MongoDB ร่วมกับ Node.js กันนะครับ
แต่บางคนอาจจะสงสัยข้ามตอน 7 ไปรึเปล่า จริงๆผมกะจะเขียนตอน 7 แต่รู้สึกว่าเนื้อหาเป็นสิ่งที่ผมเคยเขียนไปแล้วนี่นา เลยคิดว่า เอาที่เขียนอันเก่า มาใส่ในซีรีย์น่าจะง่ายกว่า ไม่อยากเขียนซ้ำครับ
เนื้อหาบทเรียน
- ตอนที่ 1 - Node.js คืออะไร + ทำการติดตั้ง Node.js และ Node.js เบื้องต้น
- ตอนที่ 2 - ทบทวนพื้นฐาน JavaScript และ Modern JavaScript ES6, ES7+
- ตอนที่ 3 - ว่าด้วยพื้นฐาน Node.js / Callback / Sync และ Async
- ตอนที่ 4 - เริ่มต้นทำเว็บด้วย Node.js และ Express.js
- ตอนที่ 5 - ลองหัดใช้ Template Engine ชื่อ Pug
- ตอนที่ 6 - เริ่มต้นกับ MongoDB
- ตอนที่ 7 - ทำ Backend API ด้วย Node.js และ MongoDB กันดีกว่า
- ตอนที่ 8 - Express Generator / Middleware (บทความนี้)
- ตอนที่ 9 - ทำระบบ Login ด้วย Passport.js
- ตอนที่ 10 - การ Hosting และ Deploy Production
เพื่อนๆอาจจะสงสัย ว่าทำไมทุกครั้งที่เราสร้าง Web ขึ้นมาด้วย Express เนี่ย เราต้องมาสร้างโฟลเดอร์ สร้างไฟล์ server สร้าง package.json
กำหนด view template ต่างๆ ด้วย ตัว Express มีทำให้เรามั้ย?
คำตอบคือมีครับ ตัว Express จะมีตัว Express Generator แยกออกมาต่างหากครับ
Express Generator
ตัว Express Generrator เป็นตัวช่วยให้เราสามารถสร้างโปรเจ็ค Express โดยใช้ Template ที่ Express มีให้ครับ
เราสามารถสั่ง Generator ผ่านตัว npx
ได้เลยครับ
npx
เป็นการใช้ Node package จาก npmjs (npm registry) โดยที่เราไม่ต้องติดตั้งลงเครื่องครับ ปกติเราต้องลงบนโฟเดอร์ หรือ global ด้วยnpm install express-generator -g
เป็นต้น
เข้า Terminal ไปที่โฟลเดอร์ที่เราต้องการ หรือสร้างใหม่ก็ได้ จากนั้น
npx express-generator --view=pug my-app
สิ่งที่ผมใส่ --view=pug
คือเราให้ Template Engine เป็น Pug ครับ ถ้าไม่ใส่ default จะเป็น Jade ซึ่งมัน deprecated ไปแล้วครับ หากมีอัพเดทในอนาคตมันอาจจะใช้ไม่ได้
จะเห็นว่าตัว Generator มันสร้างไฟล์และโฟลเดอร์ให้เราพร้อมเลย
create : my-app/
create : my-app/public/
create : my-app/public/javascripts/
create : my-app/public/images/
create : my-app/public/stylesheets/
create : my-app/public/stylesheets/style.css
create : my-app/routes/
create : my-app/routes/index.js
create : my-app/routes/users.js
create : my-app/views/
create : my-app/views/error.pug
create : my-app/views/index.pug
create : my-app/views/layout.pug
create : my-app/app.js
create : my-app/package.json
create : my-app/bin/
create : my-app/bin/www
change directory:
$ cd my-app
install dependencies:
$ npm install
run the app:
$ DEBUG=my-app:* npm start
จากนั้นลองสั่ง start server ดูครับ (อย่าลืม install dependencies ด้วยนะ)
cd my-app
npm install
Start โลด
npm start
จะได้หน้าเว็บ Express พร้อมใช้งานให้เราเลย http://localhost:3000/
ทีนี้มาดูว่าเราได้ Folder อะไรมาบ้าง
app.js
- เป็นไฟล์หลักของเรา นั่นเอง และตัว Generator ไม่ได้สั่ง listen และ start server ด้วยไฟล์นี้ ไฟล์นี้เพียงแค่รวบทุกไฟล์ไว้ด้วยกันbin/www
- เป็นเหมือนตัว Server ของเราครับ importapp.js
มา และเป็นตัว listener รวมถึงดัก Error ของ serverviews
- เป็น Folder ของ view template ที่ถูก generate มาให้แล้ว 3 ไฟล์routes
- โฟลเดอร์ที่แยก หน้าแต่ละหน้าของเว็บ โดยมี 2 หน้าเช่นindex.js
กับusers.js
ทำให้เราสามารถเขียนแยก Modules ได้นั่นเอง แล้วค่อยไปรวมกันที่ไฟล์app.js
โดยการ import จะได้ไม่ต้องเขียนทุกๆอย่างในไฟล์เดียวครับpublic
- เป็นโฟลเดอร์ของพวกไฟล์ assets ต่างๆ ทั้งรูป css และ javascript (ถ้ามี)
จะเห็นว่า เราใช้ Express Generator นั้นง่ายมากๆ และเรายังสามารถนั่งดู นั่งไล่โค๊ดที่มัน Generate มาให้เพิ่มเติมได้อีกครับ
ลองไปใช้กันดู และลองปรับเพิ่ม Module เพิ่ม Feature กันดูนะครับ ใช้ไม่ยากเลย
Express Middleware
มากันที่เรื่องของ Middleware ใน Express จริงๆแล้วเรื่อง Middleware เป็นเรื่องสำคัญ ที่จะต้องพูดถึงในโลกของ Express เลยครับ เพราะหลักๆแล้ว ตัว Middleware นี่แหละที่เป็นตัวขับเคลื่อน Express
Middleware function มันคือ function ที่สามารถเข้าถึง Object request
และ response
ได้ หรือที่เราคุ้นในชื่อย่อ req
และ res
นั่นแหละ และก็ function next
ที่เอาไว้ call middleware ถัดไป
หรือจะมองง่ายๆ ก็คือมันเป็นตัวขั้นกลาง ระหว่าง request ของ client และ response จาก server ก็ได้ครับ
ซึ่ง Middleware มันทำอะไรได้บ้าง?
- สามารถแก้ไข request และ response ได้
- สามารถจบการทำงานของ request/response ได้ (ปกติ Client ส่ง request มาให้ Server กำลังประมวลผล แต่ตัว middleware สามารถจบการทำงานโดยการส่ง response กลับไปว่า success หรือ error ประมาณนี้)
- call middleware ถัดไป ใน stack (ส่วนนี้อาจจะยังงงๆ เดี๋ยวจะอธิบายเพิ่มเติม)
ตัวอย่าง Middleware ไว้ console.log เวลามี request เข้ามา เช่น
const showLog = (req, res, next) => {
console.log('Request >> ', req)
next()
}
ฟังชั่นนี้เป็น middleware function ของ Express แล้วครับ เนื่องจากตรงตามเงื่อนไขคือ req
, res
และ callback function ชื่อ next
ตัวที่ 3 (จริงๆเราใช้ชื่ออะไรก็ได้นะ แต่ใช้ next
เพื่อให้เข้าใจง่าย เพราะเวลาเรียก next()
มันก็คือการไป next middleware ถัดไป)
ซึ่งเรานำ showLog
ที่เป็น Middlware มาใช้ปกติ เราก็ต้องใช้ app.use()
เพื่อ register middleware ก่อน
const express = require('express');
const app = express();
const showLog = (req, res, next) => {
console.log('Request >> ', req);
next();
});
app.use(showLog);
app.get('/', (req, res) => {
res.send('Hello World!');
})
app.listen(3000);
ทีนี้ ทุกครั้งที่มี request มา มันจะทำการ print ค่า req
ก่อน จากนั้นถึง callback next()
เพื่อมาอีก middleware นั่นคือ app.get('/')
จากนั้น app.get('/')
ก็ response Hello World!
กลับไปนั่นเอง เป็นการจบ cycle ของ request / response ครับ
ข้อควรระวังในการสร้าง Middleware คือ หากเราไม่ได้ response ค่ากลับ เราต้องเรียก
next()
เพื่อส่งต่อไปอีก middleware ไม่งั้น server จะค้างได้ เพราะมันไม่มี response กลับมานั่นเอง
หรืออาจจะยุบ middleware ไปใน app.use()
เลยก็ได้แบบนี้
app.use((req, res, next) => {
console.log('Request >> ', req)
next()
})
หรือในระดับ Router ก็ได้เช่นแบบนี้ ก็จะมีผลแค่เฉพาะ path /users/:id
ครับ
app.use('/users/:id', (req, res, next) => {
console.log('Request >> ', req.params)
next()
})
เมื่อมาถึงตรงนี้เพื่อนๆ ก็อาจจะร้องอ๋อละว่า เราก็ได้ใช้ Middleware กันมาก่อนแล้วนี้น่า เช่น body-parser
หรือ app.use()
ต่างๆ
หวังว่าเรื่อง Middleware จะทำให้เพื่อนๆได้เห็นภาพการทำงานของมันนะครับ เพราะในอนาคต เราจะได้ใช้ Middleware กันมากขึ้น รวมถึงตอนหน้าจะเป็นการทำ Login ครับ ซึ่งจะมี Passport.js และมี Middleware ด้วยครับ
References
เอกสารเพิ่มเติมสำหรับ Express Generator และ Middleware จริงๆแล้ว อ่านได้จาก Official Doc ได้เลยครับ
หากใครติดปัญหา หรือไม่เข้าใจตรงไหน สามารถสอบถามได้ครับ หรือหากใครเจอข้อผิดพลาด สามารถแนะนำได้เช่นกันครับ
ส่วน Source Code (อยู่ part8) สามารถเข้าไปดาวน์โหลด หรือ clone ผ่าน Github ได้เลย หากใครไม่รู้จัก Git สามารถอ่านบทความนี้เพิ่มได้ครับ Git คืออะไร ? + พร้อมสอนใช้งาน Git และ Github
ขอบคุณครับ
❤️ Happy Coding
- Authors
- Name
- Chai Phonbopit
- Website
- @Phonbopit