Note : บันทึก Workshop สร้าง Website ด้วย Node.js + Vue.js #Part 4
Step 7 — Introduce Express.js
Express.js เบื้องต้น
ในที่นี้จะเริ่มโปรเจค โดยสร้างโฟลเดอร์ ใหม่ชื่อ demo-api แล้วเข้าไปในโฟลเดอร์และเปิดด้วย VSCode และสร้างไฟล์ชื่อ index.js
จากนั้นไปที่เว็บไซต์ http://expressjs.com/ ไปที่เมนู Getting Started > Hello world แล้วไปก๊อปปี้ code มาวางใน index.js
const express = require('express') // โหลด module expressconst app = express() // สร้าง Instance expressapp.get('/', (req, res) => res.send('Hello World!')) // กำหนด path url ในการเข้าเว็บapp.listen(5000, () => console.log('Example app listening on port 5000!')) // Start Server ที่ localhost Port 5000
โดยจะเปลี่ยนหมายเลข port เป็น 5000 ไม่ให้ไปชนกับของโปรเจค nuxt.js แล้วกดเซฟ
ต่อจากนั้นต้องสร้างไฟล์ package.json ขึ้นมาก่อนโดยเปิด terminal และใช้คำสั่ง
npm init -y
npm install express
จะได้ตามภาพ
เนื่องจากตัว node.js เมื่อแก้ไขไฟล์ index.js (Server file) แล้วค่าที่แก้ไขไปจะไม่สามารถใช้งานได้จนกว่าจะต้อง Restart และ Run ใหม่
ซึ่งการทำแบบนี้ทุกครั้งนั้นเสียเวลาจึงต้องใช้ package บางตัวมาช่วยให้ Restart index.js (Server file) อัตโนมัติชื่อว่า nodemon
ต้องไปปิด server ที่ Run ไว้ในตอนแรกก่อนโดยกด Ctrl+c
และทำการติดตั้ง nodemon ลงเครื่องแบบ Global
npm install -g nodemon
หลังจากติดตั้งเสร็จให้ไปที่ terminal แล้วสั่ง Run โดยใช้คำสั่ง
nodemon index
ที่นี้หากแก้ไขที่ไฟล์ index.js ตัว nodemon จะ Restart Server ให้อัตโนมัติ
Rounting
จากโค๊ด index.js
app.get('/', (req, res) => res.send('Hello World!'))
คือ การกำหนด Routing ของ express.js ว่าถ้าเปิด Browser ไปที่ path /
จะส่งอะไรกลับมาที่ Browser
req
: คือ Request อะไรก็ตามที่ถูกส่งมาจาก Browser
res
: คือ Response อะไรก็ตามที่จะส่งกลับไป Browser
โดยการส่งค่ากลับนั้นสามารถทำได้หลายรูปแบบ เช่นส่งกลับเป็น Object
app.get('/', (req, res) => {
res.send({id : 1, name: 'Artdvp'})
})
จะถูกแปลงให้อยู่ในรูปแบบ json ซึ่งจากภาพตัวอย่างนี้ได้ที่การติดตั้ง chrome extension ชื่อ JSON viewer ไว้ที่จะช่วยจัด format json ให้ดูสวยงาม
ใน express.js เราสามารถกำหนด Routing ให้เป็นอะไรก็ได้ เช่น ลองเพิ่ม Routing ในแบบต่างๆแล้วลองเข้าตาม path ที่เราทำไว้
แต่ถ้าเข้าไป path ที่ไม่ได้กำหนดไว้ก็จะขึ้นว่า
Middleware
คือ โค๊ดที่ทำหน้าที่เป็นตัวกรอง Request ก่อนที่จะเข้ามาถึง Application ของเรา ซึ่งก่อนที่จะไป app.get หรือ app.post ต้องฝ่าน middleware ไปก่อนซึ่งมันจะเป็นตัวกลางนั่นเอง เรียกใช้งานได้โดยใช้ app.use()
เราสามารถนำ middleware ไปใช้ประโยชน์ได้หลายอย่าง เช่น เอาไว้เก็บ log ว่าใครเข้ามาเรียกใช้เว็บของเราบ้าง เอาไว้เช็คสถานะ token สำหรับ login ว่าถูกต้องหรือเปล่า
ตัวอย่าง จะแสดง LOGGED เมื่อมี Request เข้าไปที่ url ใดๆ ใส่โค๊ดลงไปแล้วเซฟกด
app.use((req, res, next) => {
console.log('LOGGED')
next()
})
เมื่อกด Refresh Browser จะเห็นข้อความที่ console ว่า LOGGED
นั่นคือการทำงานของ middleware นั่นเอง
ทีนี้จะลองให้แสดงวันที่ Request ผ่าน log ด้วย โดยจะทำการติดตั้ง package เพิ่มคือ momentjs ซึ่งเป็น library ช่วยจัดการเรื่อง Date Time ให้กดปิด server ก่อน ctrl + c
และติดตั้ง moment
npm install moment
แล้วใส่โค๊ดที่ middleware ให้แสดงวันที่ด้วยเมื่อมีการ Request เข้ามา แล้วกดเซฟ
app.use((req, res, next) => {
console.log(`LOGGED:${moment().format('MMMM Do YYYY,h:mm:ss a')}`)
next()
})
หลังจากนั้นไปที่ Browser แล้วลอง Refresh ดูหลายๆรอบ จะเห็นว่ามีวันที่และเวลาแสดงที่ console ของ server
การทำ middleware แบบกำหนด path เช่น เพิ่ม middleware ที่เมื่อเรียก path /about
จะให้ res.hello = ‘world’
app.use('/about', (req, res, next) => {
res.hello = 'world'
next()
})app.get('/', (req, res) => {
console.log('get /', res.hello)
res.send({id : 1, name: 'Artdvp'})
})app.get('/about', (req, res) => {
console.log('get /about', res.hello)
res.send("<h1>About</h1>")
})
จากตัวอย่าง ถ้าหากเรียก path อื่นที่ไม่ใช่ /about
ค่าของ res.hello ก็จะไม่ถูกส่งมาด้วย
การเขียน Routing ใน expressjs นั้นหากเว็บมี path route จำนวนมากการเขียน route ไว้ในไฟล์เดียวก็จะทำให้โค๊ดยาวมาก บวกกับการทำงานข้างในถ้ามีการต่อ Database ก็ยาวขึ้นไปอีก จึงควรแยก route ออกมาเป็นไฟล์ต่างหาก
ตัวอย่างจะทำการสร้างโฟลเดอร์ชื่อ api
และสร้างไฟล์ในโฟลเดอร์ชื่อ index.js
แล้วก็ใส่โค๊ดเพื่อทำเป็น route ลงไปที่ไฟล์ api/index.js
const express = require('express')
const router = express.Router()
module.exports = routerrouter.get('/', (req, res) => {
res.send("<h1>Home API</h1>")
})router.get('/student', (req, res) => {
res.send("<h1>Student API</h1>")
})
จากนั้้นไปที่ ไฟล์ index.js
ทำการแก้ไขโค๊ดเป็น
const route_api = require('./api')app.use((req, res, next) => {
console.log(`LOGGED:${moment().format('MMMM Do YYYY,h:mm:ss a')}`)
next()
})app.use('/api', route_api)app.get('/', (req, res) => {
res.send("Home")
})app.get('/about', (req, res) => {
res.send("<h1>About</h1>")
})
โดย require('./api')
นั่นคือการเรียกไฟล์ /api/index.js
เข้ามาใช้โดยกำหนดให้เท่ากับตัวแปร route_api
จากนั่นเรียกใช้งาน route ที่สร้างไว้ในไฟล์ api/index.js
โดยใช้
app.use('/api', route_api)
การเข้าใช้งานจะอยู่ในรูปแบบ
localhost:5000/api
localhost:5000/api/student
การสร้าง api นั้นต้องทำการออกแบบ routing ก่อนว่าจะให้มี path อะไรบ้างเช่น
GET /api/student => ดึงข้อมูลนักเรียน
POST /api/student => แก้ไขข้อมูลนักเรียน
GET /api/student/grade => ดึงข้อมูลเกรด
GET /api/activity => ดึงข้อมูลกิจกรรม
GET /api/classroom => ดีงข้อมูลห้องเรียน
GET /api/building => ดึงข้อมูลตึก
โดยสร้างไฟล์ตามชื่อ path
- student.js
- activity.js
- classroom.js
- building.js
ตัวอย่างโค๊ด student.js จะทำการประกาศ router และกำหนด path ส่วนไฟล์อื่นก็จะเหมือนกันที่ 3 บรรทัดแรก ส่วนการกำหนดให้แต่ละ route ทำงาานอะไรก็จะแตกต่างกันไป
const express = require('express')
const router = express.Router()
module.exports = routerrouter.get('/', (req, res) => {
res.send("<h1>Student</h1>")
})router.get('/list', (req, res) => {
res.send("<h1>List Student</h1>")
})
ส่วนไฟล์ api/index.js
ก็จะ require() ไฟล์ route ที่เราสร้างมาใช้งาน
const express = require('express')
const router = express.Router()
module.exports = routerrouter.use('/student', require('./student'))
router.use('/activity', require('./activity'))
router.use('/classroom', require('./classroom'))
router.use('/building', require('./building'))
การเข้าใช้งานก็เป็นตามที่ออกแบบ path เอาไว้
การรับ parameter ของ express.js
- รับ parameter แบบ Query string
localhost:5000/student?code=1234
จะรับ parameter ผ่านทาง req.query
ตัวอย่างที่ไฟล์ index.js
// GET
// localhost:5000/student?code=1234&x=5&y=8app.get('/student', (req, res) => {
console.log(req.query);
res.send("<h1>Student</h1> " + req.query.code )
})
จะเห็นว่าเมื่อเข้าไปที่ url http://localhost:5000/student
จะแสดงค่าเป็น undefined
เนื่องจากไม่ได้ส่งค่า code ไปด้วย
จากนั้นลองส่งค่าไปด้วยเช่น http://localhost:5000/student?code=123456
ตามภาพ
2. รับ parameter แบบ Url Params
localhost:5000/student/5555
จะรับ parameter ผ่านทาง req.params
ตัวอย่างที่ไฟล์ index.js ต้องกำหนด url ขึ้นต้นด้วย :
แล้วตามด้วยชื่อ parameter
app.get('/student/:code', (req, res) => {
console.log(req.query);
console.log(req.params);
res.send("<h1>Student</h1> " + req.params.code )
})
จากภาพจะเห็นว่าหากเข้าไปที่ /student
จะไม่สามารถใช้งานได้แต่ถ้าเข้า path/student/5555
จะสามารถใช้งานได้
ค่าของ /5555
ก็คือ /:code
ที่เรากำหนดไว้นั่นเอง
โดยที่ถ้าเราระบุเป็น optional โดยใส่ ?
หลังตัว url params เช่น
app.get('/student/:code?', (req, res) => {
console.log(req.query);
console.log(req.params);
res.send("<h1>Student</h1> " + req.params.code )
})
จะทำให้สามารถเข้าใช้งาน path /student
โดยมีหรือไม่มี /xxx
ต่อท้ายก็ได้หากไม่มีreq.params.code
ก็จะเป็น undefined
จบ part 4 ครับ…