สร้าง RESTful API ด้วย Node.js กับ Express เบื้องต้น
มาลองเริ่มต้นสร้าง RESTful APIs ด้วย Node.js ร่วมกับ Express ซึ่งจะไม่ได้อธิบายรายละเอียดพื้นฐานใดๆ แต่จะเน้นลงมือทำแบบตั้งโจทย์จำลอง Service ง่ายๆ ขึ้นมา เรามาเริ่มกันเลยครับ
ก่อนจะเริ่มในเครื่องจะต้องมี Node.js อยู่ก่อนนะครับ ถ้าไม่มีลองดู วิธีติดตั้งที่นี่
สร้างโปรเจ็ค
ก่อนอื่นให้เราเริ่มต้นสร้างโฟลเดอร์สำหรับเก็บโปรเจ็ค จากนั้นเข้าไปในโฟลเดอร์ และสร้างไฟล์ package.json ด้วยคำสั่งนี้
npm init -y
ติดตั้ง Express
npm install express --save
หลังจากรันคำสั่งด้านบนแล้ว ภายในโปรเจ็คของเราควรจะต้องมีโฟลเดอร์ node_modules และไฟล์ package.json
สร้าง server และ route
ทีนี้เรามาสร้าง Server แบบง่ายดูก่อนว่ามันทำงานได้ไหม เริ่มต้นให้สร้างไฟล์ server.js และเพิ่ม Code ตามด้านล่างนี้
const express = require("express");
const app = express();
const port = process.env.PORT || 3000;
app.get("/", (req, res) => {
res.send("Hello! Node.js");
});
app.listen(port, () => {
console.log("Starting node.js at port " + port);
});
อธิบายเพิ่มเติม บรรทัดบนสุดเป็นการเรียกใช้ require('express')
และถัดมาเป็นการสั่ง Execute ส่งค่าเก็บไว้ตัวแปร app
ส่วน const port = process.env.PORT || 3000;
ตรวจสอบว่ามีตั้งค่า Port ใน Environment variables หรือไม่ ถ้าไม่ให้ใช้ Default เป็น Port 3000
ส่วน app.get("/", (req, res) ...
คือ Route เป็นการกำหนด Path รวมถึง HTTP Method ต่างๆ ภายในเป็นการประมวลผลและส่งค่ากลับ
ส่วนสุดท้ายคือ app.listen(port)
รับค่า Port เพื่อสั่งให้รัน Web Server ด้วย Port ที่เรากำหนด โดยสามารถรันด้วยคำสั่งดังนี้
node server.js
เมื่อรันคำสั่งแล้วจะมีข้อความขึ้นบน Console ว่า Starting node.js at port 3000
แสดงว่าทำงานได้ถูกต้อง
จากนั้นให้เข้าไปที่ http://localhost:3000
จะได้ผลลัพธ์เป็น Hello! Node.js เพราะเรากำหนด Route ว่าถ้าเข้ามาที่ Path / ด้วย Method Get จะส่งค่าดังกล่าวกลับไป
ออกแบบ RESTful API
ตัวอย่างเป็น API ใช้งานข้อมูล User โดยจะเรียกผ่าน HTTP Method แต่ละตัวไปยัง Path ดังต่อไปนี้
- GET
/api/users
ขอข้อมูล users ทั้งหมด - GET
/api/users/:id
ขอข้อมูลเฉพาะ user id ที่ส่งเข้ามา - POST
/api/users
เพิ่ม user - PUT
/api/users/:id
แก้ไขข้อมูลเฉพาะ user id ที่ส่งเข้ามา - DELETE
/api/users/:id
ลบข้อมูลเฉพาะ user id ที่ส่งเข้ามา
จำลองข้อมูล
ให้สร้างไฟล์ db.json และเพิ่มข้อมูลตามด้านล่างเพื่อจำลองข้อมูล
[
{
"id": 1,
"username": "user1",
"name": "John",
},
{
"id": 2,
"username": "user2",
"name": "Jackson"
},
{
"id": 3,
"username": "user3",
"name": "Mary"
}
]
สร้าง API
ต่อไปนี้จะเป็นการสร้าง API ในแต่ละ Service ที่เราได้ออกแบบไว้ข้างต้น โดยจะยังแก้ไขในไฟล์ server.js เดิม ก่อนอื่นให้ import json ไฟล์ก่อน (ไว้บนสุดของ Code)
const users = require('./db')
1. API สำหรับขอข้อมูล users ทั้งหมด GET /api/users
เพิ่ม Code ด้านล่างนี้
app.get('/users', (req, res) => {
res.json(users)
})
วิธีทดสอบ API ซึ่งจะมีเครื่องมือมากมายให้ใช้ แต่ ณ ที่นี้จะใช้ Extension ของ Visual Studio Code มีชื่อว่า Thunder Client มันคือเครื่องมือที่ช่วยสร้าง API Request ลักษณะเดียวกับ Postman
เมื่อติดตั้งแล้วลองพิมพ์ http://localhost:3000/users
และกด Send เราจะเห็นรายการข้อมูล User ที่มีอยู่ ดังรูปด้านล่างนี้
2. API สำหรับขอข้อมูลเฉพาะ user id ที่ส่งเข้ามา GET /api/users/:id
เพิ่ม Code ด้านล่างนี้
app.get('/users/:id', (req, res) => {
res.json(users.find(user => user.id === Number(req.params.id)))
})
จาก Code เราจะรับ Parameter ชื่อว่า id โดยรับข้อมูลผ่าน req.params เพื่อไปค้นหาใน db.json แล้วส่งข้อมูลเฉพาะ id นั้นกลับไป ลองพิมพ์ http://localhost:3000/users/2
ผลลัพธ์ดังรูปด้านล่างนี้
3. API สำหรับเพิ่ม user POST /api/users
เพิ่ม Code ด้านล่างนี้
app.post('/users', (req, res) => {
users.push(req.body)
let json = req.body
res.send(`Add new user '${json.username}' completed.`)
})
เราจะเพิ่ม User โดยส่งข้อมูลผ่าน Request Body และรับข้อมูลผ่าน req.body
ดังนั้นเราจำเป็นที่จะต้องใช้ Middleware ซึ่งจะเป็นตัวขั้นก่อนเข้าถึง Route เพื่อแยกวิเคราะห์ body message ที่เข้ามา
กรณีเวอร์ชั่น Express 4.16.0+ ขึ้นไป เราสามารถเรียกใช้ Built-in middleware โดยตรงได้เลยดังนี้
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
กรณีเวอร์ชั่นต่ำกว่า Express 4.16.0 ให้ติดตั้ง body-parser ตามด้านล่างนี้
npm install body-parser --save
และเรียกใช้งาน body-parser ดังด้านล่างนี้
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
ทดสอบโดยเลือก Method เป็น Post พร้อมส่ง request body เป็นข้อมูลของ User ที่จะเพิ่มในรูปแบบ Json Content ไปยัง http://localhost:3000/users
ผลลัพธ์ดังรูปด้านล่างนี้
4. API สำหรับแก้ไขข้อมูลเฉพาะ user id ที่ส่งเข้ามา PUT /api/users/:id
เพิ่ม Code ด้านล่างนี้
app.put('/users/:id', (req, res) => {
const updateIndex = users.findIndex(user => user.id === Number(req.params.id))
res.send(`Update user id: '${users[updateIndex].id}' completed.`)
})
ทดสอบโดยเลือก Method เป็น Put พร้อมส่ง request body เป็นข้อมูลของ User ที่จะแก้ไขในรูปแบบ Json Content และ Parameter ชื่อว่า id ไปยัง http://localhost:3000/users/2
ผลลัพธ์ดังรูปด้านล่างนี้
5. API สำหรับลบข้อมูลเฉพาะ user id ที่ส่งเข้ามา DELETE /api/users/:id
เพิ่ม Code ด้านล่างนี้
app.delete('/users/:id', (req, res) => {
const deletedIndex = users.findIndex(user => user.id === Number(req.params.id))
res.send(`Delete user '${users[deletedIndex].username}' completed.`)
})
ทดสอบโดยเลือก Method เป็น Delete พร้อมส่ง Parameter ชื่อว่า id ไปยัง http://localhost:3000/users/2
ผลลัพธ์ดังรูปด้านล่างนี้
Code ในไฟล์ server.js ทั้งหมดเมื่อรวมกันแล้วจะเป็นดังนี้
const users = require('./db')
const express = require("express");
const app = express();
const port = process.env.PORT || 3000;
// - เวอร์ชั่น Express 4.16.0+ ขึ้นไป
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
// - เวอร์ชั่นต่ำกว่า Express 4.16.0+
// const bodyParser = require('body-parser')
// app.use(bodyParser.json())
// app.use(bodyParser.urlencoded({ extended: true }))
app.get("/", (req, res) => {
res.send("Hello! Node.js");
});
app.get('/users', (req, res) => {
res.json(users)
})
app.get('/users/:id', (req, res) => {
res.json(users.find(user => user.id === Number(req.params.id)))
})
app.post('/users', (req, res) => {
users.push(req.body)
let json = req.body
res.send(`Add new user '${json.username}' completed.`)
})
app.put('/users/:id', (req, res) => {
const updateIndex = users.findIndex(user => user.id === Number(req.params.id))
res.send(`Update user id: '${users[updateIndex].id}' completed.`)
})
app.delete('/users/:id', (req, res) => {
const deletedIndex = users.findIndex(user => user.id === Number(req.params.id))
res.send(`Delete user '${users[deletedIndex].username}' completed.`)
})
app.listen(port, () => {
console.log(`Starting node.js at port ${port}`);
});
หวังว่าบทความนี้คงมีประโยชน์ครับ