มาลองเริ่มต้นสร้าง 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 ดังต่อไปนี้

  1. GET /api/users ขอข้อมูล users ทั้งหมด
  2. GET /api/users/:id ขอข้อมูลเฉพาะ user id ที่ส่งเข้ามา
  3. POST /api/users เพิ่ม user
  4. PUT /api/users/:id แก้ไขข้อมูลเฉพาะ user id ที่ส่งเข้ามา
  5. 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}`);
});

หวังว่าบทความนี้คงมีประโยชน์ครับ