ทำ Backend API ด้วย Node.js และ MongoDB กันดีกว่า

ทำ Backend API ด้วย Node.js และ MongoDB กันดีกว่า

2,490฿คอร์สสอนสร้างเว็บไซต์ HTML/CSS สำหรับมือใหม่ + พร้อม Workshop


สวัสดีครับ วันนี้มาแนะนำการเขียน RESTful API สำหรับ Node.js ด้วยการใช้ Express.js และ MongoDB กันนะครับ ซึ่งจริงๆแล้วบทความ API ด้วย Node.js นั้นเคยเขียนไว้แล้วหลายบทความเลย เช่น

และส่วนใหญ่ก็นานแล้ว 4-5 ปี ฉะนั้น ก็เลยคิดว่าทำเป็นบทความใหม่เลยน่าจะดีกว่าครับ เนื่องจากว่ามีคนสนใจและยังเข้ามาอ่านบทความเก่าๆอยู่พอสมควร

Table of Contents

Step 1 : Create Project

เริ่มต้นทำการสร้างโปรเจ็คด้วย npm init ขึ้นมา หรือจะสร้างไฟล์ package.json ขึ้นมา และตั้งชื่อ name กับ version ก็พอ ก็ได้ครับ

mkdir my-app && cd my-app
npm init

จากนั้น ติดตั้ง express : สำหรับเป็น Web Framework เอาไว้จัดการ Routing

npm install express

สร้างไฟล์ server.js ขึ้นมา ไฟล์นี้จะเป็นไฟล์หลักของเรา

const express = require('express')
const app = express()

app.get('/', (req, res) => {
  res.json({ message: 'Ahoy!' })
})

app.listen(9000, () => {
  console.log('Application is running on port 9000')
})

สำหรับใครที่เคยใช้ Express มาก่อน สามารถ generate โปรเจ็ค ด้วย express-generator ได้นะครับ ข้อดีคือมีไฟล์ routing, view template ให้เลย รายละเอียด Express Generator

ทดลอง Start server ด้วยคำสั่ง

node server.js

หรือจะทำเป็น script เพื่อสั่ง npm start ก็ได้ครับ ใน package.json เพิ่มลงไป

{
  "scripts": {
    "start": "node server.js"
  }
}

ตัว Server จะรันด้วย port 9000 ครับ ตัวอย่างหน้าเว็บ เมื่อเปิด http://localhost:9000

ตัวอย่างหน้าเว็บ

แนะนำติดตั้ง Chrome Extension ชื่อ JSON Viewer เพื่อให้สามารถดู JSON ในหน้าเว็บได้สะดวกขึ้น

Step 2 : Express Routing

จากโค๊ดไฟล์ server.js จะเห็นว่า เรามีการเรียก

app.get('/', (req, res) => {
  res.json({ message: 'Ahoy!' })
})

ตัว app.get() เป็น function ของ Express ที่เอาไว้กำหนด routing (url) สำหรับ HTTP GET ของเว็บไซต์เรา และรับ parameter 2 ตัวครับ ตัวแรกเป็น

  • path ที่เราต้องการ เช่น / หรือ /home หรือ /about อะไรพวกนี้
  • callback function : ที่เป็น function ที่มี parameter เป็น request และ response
  • request (req) : จาก callback คือค่าที่รับมาจากทาง Client (Browser)
  • response (res) : เป็น object ที่เราจะ return กลับไปให้ Client (Browser) ตัวอย่างส่ง JSON กลับไป ด้วย res.json()

Route Method

ใน Express เราสามารถกำหนด HTTP Method ได้ด้วยการเรียก function ของ app ได้เลย เช่น

// สำหรับ HTTP GET
app.get('/', fn)

// สำหรับ HTTP POST
app.post('/', fn)

// PUT และ DELETE
app.put('/', fn)
app.delete('/', fn)

หรือสามารถใช้ app.all('/', fn) เพื่อ match ทุกๆ HTTP Method ก็ได้เช่นกันครับ

Route Path

การกำหนด Route path เราสามารถกำหนดเป็น String, RegEx หรือใส่ route parameter ได้

app.get('/a/', fn)

ในตัวอย่าง กำหนดแบบ String ถ้าเราเข้าเว็บแล้วมี url ที่ไม่ใช่ / มันก็จะไม่แสดง message

app.get(/hello/, fn)

แบบใช้ RegEx ถ้าหากว่า url ที่เราเข้ามีคำว่า hello มันก็จะแสดง message หมด เช่น

หรือการกำหนด parameter ก็ได้ เช่น

app.get('/hello/:message', (req, res) => {
  const { params } = req

  res.json({
    message: 'Ahoy!',
    params
  })
})

เราสามารถ กำหนด dynamic url ได้ด้วยการใส่ semicolon แล้ว access ค่าด้วย req.params ตัวอย่างเช่น แก้ไขไฟล์ server.js เป็นแบบนี้

const express = require('express')
const app = express()

app.get('/hello/:message', (req, res) => {
  const { params } = req
  res.json({ message: 'Ahoy!', params })
})

app.listen(9000, () => {
  console.log('Application is running on port 9000')
})

เมื่อเข้า url http://localhost:9000/hello/this-is-message จะได้ response แบบในรูป

อย่าลืม stop server ด้วย CTRL + C ก่อน แล้ว start server ใหม่อีกครั้งครับ ถ้าอยากได้ server restart ทุกครั้งที่กดเซฟ สามารถติดตั้ง Nodemon เพิ่มเติมได้

Example 2

ทดลองเปลี่ยน url เป็น /hello/message ที่ต้องการได้ เพื่อดู response ที่ส่งกลับได้ครับ

สามารถดูเรื่อง Express Routing เพิ่มเติมได้

Step 3 : Making first API

ต่อมาครับ เริ่มทำ API จริงๆแล้ว โดยตอนนี้สิ่งที่ผมจะทำคือ เป็น API สำหรับรายละเอียดของสินค้า โดยกำหนด Resource Endpoint ไว้ดังนี้

  • GET /products : สำหรับแสดงรายการ Product ทั้งหมด
  • POST /products : ไว้สำหรับการเพิ่มข้อมูล Product ใหม่
  • GET /products/1 : สำหรับแสดงรายละเอียดของ Product จาก id = 1
  • PUT /products/1 : สำหรับไว้อัพเดทค่า Product ที่มี id = 1
  • DELETE /products/1 : สำหรับลบข้อมูลของ Product ที่มี id = 1

โดยจะเห็นว่าผมกำหนด endpoint เพื่อใช้ HTTP Method (GET, PUT, POST, DELETE) ให้สอดคล้องกับ path name ทำให้ API ดูอ่านง่ายกว่า และใช้ noun แบบ plurals แทนการตั้งโดยใช้ verb แบบ getProductAll, getProductById, createNewProduct อะไรพวกนี้

ต่อมาหลักการสำหรับ API Design คร่าวๆละกันครับ นอกเหนือจากนี้คือ

HTTP Method

จากตัวอย่างด้านบน ขอเสริมเพิ่มอีกนิดครับ คือเราจะใช้ HTTP Method มาช่วยในการกำหนด API Endpoint ให้กับ server ครับ เพราะว่าอะไร เพราะว่าเรามี HTTP Method อยู่แล้ว เราเลยเอามาใช้ประโยชน์ และการตั้ง endpoint จะได้ดูง่ายขึ้น คือ

  • GET : สำหรับขอ request จาก server เช่น รายชื่อทั้งหมด หรือรายชื่อเดี่ยว
  • PUT : สำหรับ update ค่า โดยเราจะส่งมากับ payload
  • POST : สำหรับ create หรือเพิ่มค่าใหม่
  • DELETE : สำหรับลบค่า

HTTP Response

  • 200 OK : จะเป็น response ปกติที่ไม่มีอะไรผิดพลาด
  • 201 created : สำหรับ return กรณี create new data (ใช้กับ POST)
  • 204 no content : สำหรับกรณี DELETE (ลบข้อมูลเรียบร้อยแล้ว) ก็จะ response empty กลับไป
  • 400 Bad request : จะใช้กรณีที่ Server เรารับค่ามาไม่ตรงกับ API Design ไว้ เช่น ส่ง payload มาเกิน
  • 401 Unauthorized : สำหรับกรณีที่เราไม่รู้ว่า client ที่ request มาเป็นใคร คือยืนยันตัวไม่ได้ เช่น ไม่มี token หรือ token ผิด
  • 403 forbidden : สำหรับกรณีที่เรา authentication ผ่าน คือรู้ว่าใคร แต่ authorize ไม่ผ่าน คือ url นี้ไม่อนุญาตให้เข้าถึง เช่น เป็น user แต่ขอ request เข้าถึงหน้า admin ก็จะไม่อนุญาต เป็นต้น
  • 404 not found อันนี้น่าจะปกติเหมือนเว็บทั่วไป คือกรณี request url ไม่มีในระบบ
  • 5xx : ส่วนตระกูล 500, 503 จะเกิดจากปัญหาที่ฝั่ง Server ของเรา เช่นระบบล่ม code crash เป็นต้น

Naming

ต่อมาเรื่องการตั้งชื่อเล็กน้อย จริงๆแล้วตัว request และ response ของ JSON เราจะตั้งชื่อยังไงก็ได้ ที่นิยมมี 2 แบบคือ camelCase และ snake_case ซึ่งก็แล้วแต่ภาษาที่ implement ทั้งฝั่ง client/server หรือแล้วแต่ตกลงกันครับ เช่น

{
  "data": {
    "categoryId": "10001",
    "productName": "Item 1"
  }
}

เทียบกับ

{
  "data": {
    "category_id": "10001",
    "product_name": "Item 1"
  }
}

โดยในบทความนี้ขอยึดแบบ camelCase นะครับ เพราะเป็น Naming ที่ JavaScript ส่วนใหญ่ใช้

Response

สำหรับ Response data เราสามารถส่งได้แบบ envelop กับไม่ได้ envelop ครับ (คือจะหุ้มด้วย {} ) เช่น

แบบ Envelop

{
  data: [{
    id: 1
  }, {
    id: 2
  }]
}
// หรือ
{
  data: {
    id: 1,
    name: 'test 1'
  }
}

และแบบไม่ enveloped

[{
  id: 1
}, {
  id: 2
}]

// หรือ
{
  id: 1,
  name: 'test 1'
}

ต่อมาที่ไฟล์ server.js ทำการเพิ่ม endpoint ต่างๆตามที่ requirement กำหนดไว้ ด้านบน เป็นดังนี้

const express = require('express')
const app = express()


// mock data
const products = [{
  id: '1001',
  name: 'Node.js for Beginners',
  category: 'Node',
  price: 990
}, {
  id: '1002',
  name: 'React 101',
  category: 'React',
  price: 3990
}, {
  id: '1003',
  name: 'Getting started with MongoDB',
  category: 'MongoDB',
  price: 1990
}]

app.get('/products', (req, res) => {
  res.json(products)
})

app.get('/products/:id', (req, res) => {
  const { id } = req.params
  const result = products.find(product => product.id === id)
  res.json(result)
})

app.post('/products', (req, res) => {
  const payload = req.body
  res.json(payload)
})

app.put('/products/:id', (req, res) => {
  const { id } = req.params
  res.json({ id })
})

app.delete('/products/:id', (req, res) => {
  const { id } = req.params
  res.json({ id })
})

app.listen(9000, () => {
  console.log('Application is running on port 9000')
})

โดยที่ตอนนี้เรายังไม่มีค่าจริงจาก Database ก็เลยใช้ mock data ขึ้นมาก่อนครับ

ทดสอบโดยการเปิด Browser

Nodejs step 3

Step 4 : Testing with Postman

ต่อมาครับ เราสามารถเทส Url endpoint ได้เฉพาะ HTTP GET การจะเทส PUT/POST/DELETE เราจำเป็นต้องมี Tool ช่วยครับ และ Tool ที่ง่ายและเป็นที่นิยมก็คือ Postman นั่นเองครับ

Postman

ทดสอบ HTTP GET

ซึ่ง Postman เราสามารถกำหนด URL ได้เหมือนกับ Browser เลยครับ และสามารถเลือก HTTP Method ได้ตามรูปด้านล่างครับ

Postman manual

ทดลองกด Send ดูได้เลย เลือก GET และ url เป็น http://localhost:9000/products จะเห็น result แบบเดียวกับเปิดบน Browser

ทดสอบ HTTP POST

ต่อมาลองเปลี่ยนเป็น POST และกำหนด Body เป็น raw และ content-type เป็น JSON application/json ดังรูปด้านล่างครับ

Postman POST

ทดสอบดูและได้ผลลัพธ์คือ !!!! ว่างเปล่าครับ

เพราะว่า Express ไม่สามารถรับค่า request body ได้ default จะเป็น undefined จะสามารถใช้ได้ก็ต่อเมื่อเราใช้ body-parser middleware ครับ

เพิ่มโค๊ด ไปที่บรรทัด 4 ของไฟล์ server.js เป็นแบบนี้ครับ

const express = require('express')
const app = express()

app.use(express.json())

เมื่อก่อน body-parser เป็น middleware ที่มาพร้อม Express ก่อนจะเอาออกไปแยกเป็น library ชื่อ body-parser ก่อนที่เวอร์ชั่นหลังๆ ก็นำกลับมารวมกันอีกครั้งครับ ฉะนั้นหากเจอว่าใช้ app.use(bodyParser.json()) ก็คือแบบเดียวกันนะครับ

ลองดูผลลัพธ์ใหม่

Postman Result

ต่อมาการเทส PUT/DELETE ก็ทำเช่นเดียวกันกับ POST ครับ คือเลือกเปลี่ยน HTTP Method โดย

  • PUT จะส่ง body แบบเดียวกันกับ POST
  • DELETE ไม่ต้องส่ง body อะไรไป

Step 5 : Connect MongoDB

ต่อมาหลังจากมี API คร่าวๆแล้ว ต่อมาเราจะมา Connect MongoDB กันนะครับ ด้วย Mongoose

สำหรับใครที่ไม่เคยใช้ MongoDB แนะนำอ่านบทความ MongoDB ประกอบครับ MongoDB คืออะไร? + สอนวิธีใช้งานเบื้องต้น

ทำการติดตั้งตั้งผ่าน npm

npm install mongoose

ต่อมาทดสอบให้แน่ใจก่อนว่าเรารัน Mongo Server อยู่ เปิด Console/Terminal หรือ RoboMongo (ที่เป็น GUI) ดูก็ได้ครับ

mongo

# show databases ทั้งหมด
show dbs

ถ้า Mongo start อยู่แล้วก็ไม่มีปัญหาครับ ถ้ายัง ก็อย่าลืม start MongoDB ขึ้นมานะครับ จากนั้นทำการเพิ่มโค๊ดส่วนนี้ลงไป

const express = require('express')
const app = express()
+ const mongoose = require('mongoose')

app.use(express.json())

+ mongoose.connect('mongodb://localhost:27017/node-api-101', { useNewUrlParser: true })

เพื่อสั่งให้ Mongoose ทำการ connect MongoDB บนเครื่องเรา โดยใช้ database ชื่อ node-api-101 (สามารถเปลี่ยนชื่อได้ตามต้องการ)

  • { useNewUrlParser: true } : ส่วนนี้เป็น Option ถ้าไม่ใส่จะ warning ว่าการ connect mongodb ด้วย url แบบ string ในอนาคตจะ depreacated แล้ว (ซึ่งไม่ใส่ก็ได้ แต่จะมี warning แค่นั้น)

ต่อมา สร้าง Model ง่ายๆ และ add ลง database ทุกครั้งที่ start server แบบนี้

const express = require('express')
const app = express()
const mongoose = require('mongoose')

mongoose.connect('mongodb://localhost:27017/node-api-101', { useNewUrlParser: true })

app.use(express.json())

// สร้าง database schema
const Cat = mongoose.model('Cat', { name: String })

// สร้าง instance จาก model
const kitty = new Cat({ name: 'JavaScript' })

// save ลง database (return เป็น Promise)
kitty.save().then(() => console.log('meow'))

จากนั้นลอง Start server ใหม่ แล้วดูผลลัพธ์ใน Mongo เราต้องมี db และ collection ใหม่ เป็นค่า JavaScript ที่ถูกเซฟไปนั่นเอง

Mongo Console Cat

Mongoose Schema

ใน Mongoose เราต้องทำการกำหนด Model เป็น Schema สำหรับ Collection ที่จะเซฟครับ ซึ่งตัวอย่างคือ Product ฉะนั้นก็จะต้องทำการสร้าง schema ของ Product ขึ้นมา แบบนี้

ทำการสร้างไฟล์ใหม่ชื่อ product.js ไว้ในโฟลเดอร์ใหม่ เป็น models

const mongoose = require('mongoose')
const Schema = mongoose.Schema

const productSchema = new Schema({
  name:  String,
  category: String,
  price: Number,
  tags: [String]
})

const ProductModel = mongoose.model('Product', productSchema)

module.exports = ProductModel

โดย Schema นั้นเพียงแค่ระบบ Type ให้มันว่าจะเป็นอะไรตัวอย่างเช่น String, Number หรือ [String] สำหรับ Array ที่ข้างในเป็น String นั่นเองครับ (ซึ่งจะมี type พิเศษคือ ObjectId เป็น type สำหรับ unique id ของ MongoDB ครับ)

จากนั้นก็ทำการสร้าง mongoose.model() ด้วย Schema ที่เรา define ไว้ แล้วก็ export ไปให้ไฟล์อื่นสามารถ import Model มาใช้ได้ครับ

Step 6 : CRUD with Mongoose

ต่อมาทำ CRUD (Create, Read, Update, Delete) ข้อมูลจาก Database กันครับ โดยเราจะเปลียนทั้งหมดจากที่ใช้ mock data เป็น database จริงๆ

Save data

ต่อมา ผมกลับมาแก้ไฟล์ server.js ตรงส่วนของ app.post('/products') เพื่อที่จะรับค่าจาก Postman แล้ว save ข้อมูลลง Database ครับ

const express = require('express')
const app = express()
const mongoose = require('mongoose')
const Product = require('./models/product')

mongoose.connect('mongodb://localhost:27017/node-api-101', { useNewUrlParser: true })

app.use(express.json())

// mock data
const products = [{}]

app.post('/products', async (req, res) => {
  const payload = req.body
  const product = new Product(payload)
  await product.save()
  res.status(201).end()
})

โดย ผมใช้ async/await เข้ามาใช้จัดการข้อมูล Promise แทน then() ยังคงเป็น async อยู่ โดย new Product(payload) ทำการสร้าง object product จาก payload ที่ได้รับจาก Postman (ซึ่งต้องตรง schema กับที่เราสร้างไว้ใน model ด้วยนะครับ) เมื่อทำการ save product เรียบร้อยแล้ว ก็ให้ return HTTP Status 201 กลับไป ด้วยคำสั่ง res.status(201).end()

ทดสอบรัน Server และลองยิง Postman แบบ POST เพื่อสร้าง product ก้อนใหม่ มี body แบบนี้

{
	"name": "My Product from Postman",
	"category": "Tool",
	"price": 0,
	"tags": ["test1", "test2", "tag1"]
}

ผลลัพธ์ที่ได้ต้องเป็นแบบนี้ครับ

Postman create new product

โดยที่ค่า _id ที่ถูกเก็บไว้ใน MongoDB จะเป็น unique id ที่ MongoDB generate ไว้ให้นะครับ สามารถเอาไปใช้เป็น unique id ต่างๆ ได้ เช่น url สำหรับ detail หรือ edit หรือ delete product ด้วย _id

find()

ต่อมาเราสามารถ Query collection ผ่าน Mongoose ได้ด้วยคำสั่ง find() ครับ เช่น

Product.find() // ค้นหาทั้งหมด

Product.find({}) // ค้นหาทั้งหมด

หรือ Query โดยกำหนด condition คือ

// ค้นหา Product ทั้งหมด ที่มี name = 'item 1'
Product.find({ name: 'item 1' })

// ค้นหา Product ทั้งหมด ที่มี name = 'item 2' และ price = 0
Product.find({ name: 'item 2', price: 0 })

มาแก้ไขส่วน app.get('/products') กันบ้าง ให้ Query ข้อมูลแทนข้อมูล mock data ครับ

app.get('/products', async (req, res) => {
  const products = await Product.find({})
  res.json(products)
})

findById() และ findOne()

ต่อมาการ query โดยได้ result เป็นค่าๆเดียวๆครับ คือ findById โดยใช้ ObjectId ของ MongoDB ครับ เช่น

// หา Product ที่มี _id = 5d556f0dce881660923ed0aa
Product.findById('5d556f0dce881660923ed0aa')

หรือใช้ findOne() ก็ได้ เช่นกันคือ

Product.findOne({ _id: '5d556f0dce881660923ed0aa' })

// หา product ที่มี name = 'item 1'
Product.findOne({ name: 'item 1' })

จะเห็นได้ว่า findById() มีค่าเท่ากับ findOne({ _id: '' }) ถ้าเราหา _id เท่านั้น

กลับมาแก้ server.js ของ app.get('/products/:id') เพื่อให้ Query ข้อมูลจาก Database กันครับ

app.get('/products/:id', async (req, res) => {
  const { id } = req.params
  const product = await Product.findById(id)
  res.json(product)
})

Update

ต่อมาการ Update ข้อมูล เราใช้ฟังค์ชั่น findByIdAndUpdate() โดยอัพเดทจาก _id ครับ และค่าที่ต้องการอัพเดทจาก payload ที่ user ส่งมา

const data = {
  newValue: 'new data'
}

Product.findByIdAndUpdate('ObjectId', data)

แต่กรณีที่ update ปกติ Mongo จะทำการ เอาค่าใหม่ไปทับค่าเก่าเลย ฉะนั้นเราต้องใช้ $set เพื่อให้มันอัพเดทเฉพาะค่าที่เราส่งไป ค่าอื่นยังคงอยู่เหมือนเดิม แบบนี้

const data = {
  $set: {
    newValue: 'new data'
  }
}
Product.findByIdAndUpdate('ObjectId', data)

กลับมาปรับ server.js สำหรับ app.put('/products/:id') กันครับ

app.put('/products/:id', async (req, res) => {
  const payload = req.body
  const { id } = req.params

  const product = await Product.findByIdAndUpdate(id, { $set: payload })
  res.json(product)
})

Delete

ต่อมาการ Delete ครับ เราจะใช้คำสั่ง findByIdAndDelete() เพื่อหา product ที่มี _id ที่เราต้องการ คล้ายๆ findByIdAndUpdate() เพียงแต่ว่าไม่ต้องส่ง data อะไรไป เช่น

Product.findByIdAndUpdate('5d5572420656d66c762e3c65')

นอกเหนือจากนี้เรายังลบ product ที่ตรงเงือนไขเราได้ด้วยคำสั่ง findOneAndDelete() เช่น

// ลบ product ที่มี name = item
Product.findOneAndDelete({ name: 'item 1' })

มาแก้ server.js ส่วน app.delete() กันครับ เป็นแบบนี้

app.delete('/products/:id', async (req, res) => {
  const { id } = req.params

  await Product.findByIdAndDelete(id)
  res.status(204).end()
})

Options

เราจะสังเกตเห็นว่า Mongoose มันจะ generate __v field มาให้เรา เราสามารถเอาออกได้ ด้วยการใส่ option ในตอนที่ define schema ครับ และนอกจากนี้ ผมก็จะใช้ option timestamps ด้วยครับ เพื่อให้มัน auto generate createdAt และ updatedAt เป็นเวลาที่ data นั้นถูกสร้าง หรือถูก edit นั่นเอง

เพิ่ม { timestamps: true, versionKey: false } ลงไปที่เป็น parameter ที่ 2 ของ Schema แบบนี้ครับ

const productSchema = new Schema({
  name:  String,
  category: String,
  price: Number,
  tags: [String]
}, { timestamps: true, versionKey: false })

เป็นอันเรียบร้อย ครั้งต่อไปที่ data ถูกสร้างลง Database ก็จะมี createdAt และ updatedAt และลบ __v ให้เราอัตโนมัติ

และส่วนสุดท้าย กรณีที่เรา connect mongodb บางครั้งมี Error เราอาจจะไม่รู้ว่า error อะไร เราสามารถ handle มันได้ด้วยคำสั่งนี้ครับ เพิ่มลงที่ server.js หลังจาก mongoose.connect()

mongoose.connection.on('error', err => {
  console.error('MongoDB error', err)
})

Done!

สรุป

ตอนนี้ เราก็ได้ Backend API ง่ายๆ ด้วยการใช้ Express.js + Mongoose สำหรับทำ RESTFul API กันไปแล้ว รวมถึงสามารถใช้ Postman ในการเทส HTTP Method ต่างๆด้วย ที่เหลือผู้อ่านก็ลองไปดู Mongoose เพิ่มเติมนะครับ ว่ามันสามารถ Query อะไรได้บ้าง Query และกำหนด limit หรือ order ยังไง รวมถึง การเทสด้วย Postman ก็นับว่ามีประโยชน์ไม่น้อย ในการทำงานจริง

หวังว่าบทความนี้จะเป็นประโยชน์สำหรับผู้เริ่มต้นที่จะหัด Node.js และหัดทำ Backend API นะครับ หากติดปัญหาตรงส่วนไหน หรือขั้นตอนไหนไม่เคลียร์ สามารถสอบถามได้เลยครับ

สุดท้าย Source Code ของบทความนี้เช่นเคยครับ เผื่อใครติดปัญหาสามารถ Clone ไปลองดูได้ครับ

Source Code

หรือจะดู Demo ก็ URL นี้เลยครับ

Happy Coding

Chai Phonbopit

Chai Phonbopit: Software Engineer แห่งหนึ่ง • ผู้ชายธรรมดาๆ ที่ชื่นชอบ Node.js, JavaScript, React และ Open Source มีงานอดิเรกเป็น Acoustic Guitar และ Football นอกจากเขียนบล็อคที่เว็บนี้แล้ว ก็มีเขียนที่ https://medium.com/@Phonbopit ครับ