NodeJS ตอนที่ 5 [Restful API]

การเขียนเว็บเซอร์วิส หรือ เว็บ Api (Application Programming Interface) เพื่อให้เทคโนโลยแพลตฟอร์มต่างๆสามารถแลกเปลี่ยนข้อมูลกันได้ ไม่ว่าจะเป็น OS ,Web ,Mobile Application  นั้น มี 2 มาตรฐานที่ได้รับความนิยม ได้แก่

  • SOAP (Simple Object Access Protocol)
  • REST (Representational state transfer)

ในการพัฒนาเว็บเซอร์วิสเมื่อ 4-5 ปีที่แล้ว SOAP ได้รับความนิยมมาก แต่ปัจจุบัน คุยกับนักพัฒนาหลายท่านแล้ว ถ้าไม่ปรับปรุงของเดิมที่เคยทำไว้แล้ว ก็มีแต่จะใช้ REST เป็นหลัก วันนี้เราจะมาทำความรู้จักบางส่วนที่จำเป็นของ REST เพื่อนำมาใช้ในการพัฒนา Web Api ใน NodeJS กัน

REST 

  • สื่อสารผ่านโปรโตคอล http ถ้าสังเกตเวลาเราเปิด Browser อย่าง Chrome , Firefox , Safari แล้วเข้าเว็บไซต์แล้วพิมพ์ https://thaiprogrammer.org ก็คือรูปแบบการสื่อสารด้วย protocol http ที่เราคุ้นเคยกัน
  • สื่อสารด้วย verbs method หลักๆที่นิยมกัน คือ GET, POST , PUT , DELETE
  • ช่องทางการสื่อสารจะอ้างถึง Uniform Resource Identifiers (URIs) หรือบางครั้งเรานิยมเรียกว่า Routing  เช่น https://thaiprogrammer.org/category/news/thai-programmer-network-news/
  • การสื่อสารจะเป็นการส่งคำขอจาก Request จากต้นทางไปยัง ปลายทาง และปลายทางจะตอบสนอง (Respose) กลับมา ในการเขียนโปรแกรมกับ REST เราก็จะเห็นออบเจค Request กับ Response อยู่บ่อยๆไม่ว่าจะพัฒนาด้วยภาษาใดก็ตาม

[img class=”aligncenter” src=”/wp-content/uploads/2016/02/rest.png” ]

รูปที่ 1 แสดง Flow การร้องขอและตอบสนองของ REST API

จากรูป ฝั่ง Client จะส่งคำขอ ไปหาภายทาง ซึ่งใน http โปรโตคอล จะเปรียบเสมือนเอกสารชุดหนึ่ง ที่มีหัวกระดาษ (Header) และเนื่อหาที่อยู่ข้างในตัวเอกสาร (Body) พร้อมประเภทคำสั่ง GET,POST,PUT ,DELETE ไปยังเส้นทางที่ระบุถึงปลายทาง เช่น http://myweb/getdata ฝั่งปลายทางก็จะตอบรับคำขอกลับไป พร้อมทั้งสถานะการตอบกลับที่เป็นมาตรฐาน ดังนี้

  • 200 OK สถานะตอบไปยังต้นทางได้ปกติ
  • 500 internal error มีข้อผิดผลาดที่ปลายทาง
  • 401 Unauthorised ไม่มีสิทธิเข้าถึง URIs ดังกล่าว
  • 404 not fount หา URIs ดังกล่าวไม่เจอ

การใช้ http method แต่ละตัว มีจุดประสงค์ ดังนี้

  • GET – ขอข้อมูล
  • POST – เพิ่มข้อมูล
  • PUT – แก้ไขข้อมูล
  • DELETE – ลบข้อมูล

จากประสบการณ์รูปแบบการรับส่งที่แตกต่าง มีแค่สองฝั่งคือ GET กับ POST,PUT ,DELETE ซึ่งสามอย่างหลังใช้อะไรแทนกันก็ได้ หรือบางโปรเจคผมใช้ POST อย่างเดียวเลย น่าจะขึ้นอยู่กับการใช้สื่อความหมายมากกว่า เพราะสุดท้ายฝั่งเซิร์ฟเวอร์จะทำงานแบบไหนนั้นก็ขึ้นอยู่กับที่เราเขียนโปรแกรมไว้

มาเริ่มเขียน REST แบบง่ายๆกันดีกว่า

1.ติดตั้งไลบรารี่ body-parser

npm install body-parser

2. สร้างไฟล์ชื่อ ch5_restapi.js ป้อนโค้ด ดังนี

var express = require("express");
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json());
var data =[];

app.get('/get', function (req, res) {
  console.log('get data');
  res.send(data);
});

app.post('/add', function (req, res) {
    console.log('add data');
    req.body.id = data.length +1;
    data.push(req.body);
    res.send(data);
});

app.put('/edit', function (req, res) {
  if(req.body.id)
    data[req.body.id-1] = req.body;
  console.log("edit data!");
  res.send(data);
});

app.delete('/delete', function (req, res) {
  if(req.body.id)
    data.splice(req.body.id-1,1);
  console.log("delete data!");
  res.send(data);
});

app.listen(3000);
console.log("My Service is listening to port 3000.");

3. Browser Chrome ติดตั้ง Plugin ชื่อ Postman เพื่อทดสอบ Rest Api

[img class=”aligncenter” src=”/wp-content/uploads/2016/02/chormepostman.png”]

4. รันไฟล์ ch5_restapi.js

node ch5_restapi.js

5. เปิด plugin postman ทดสอบฟังก์ชั่น add โดยกำหนดค่าต่างๆ ดังรูป แล้วกดปุ่ม Send เพื่อทดสอบ

[img class=”aligncenter” src=”/wp-content/uploads/2016/02/postmansetup.png”]

6. ทำการเพิ่ม item ต่างๆ และส่งข้อมูลทีละรายการ ดังนี้

  • {“item”:”banana”}
  • {“item”:”orange”}
  • {“item”:”pie apple”}

7. ทดสอบฟังก์ชั่น edit โดยเปลี่ยน url เป็น http://localhost:3000/edit และ method เป็น PUT ป้อนค่า แล้วกดปุ่ม Send ดังนี้
{“id”:2,”item”:”mango”}

8. ทดสอบฟังก์ชั่น delete โดยเปลี่ยน url เป็น http://localhost:3000/delete และ method เป็น DELETE ป้อนค่า แล้วกดปุ่ม Send ดังนี้

{“id”:3}

9. ทดสอบฟังก์ชั่น get โดยเปลี่ยน url เป็น http://localhost:3000/get และ method เป็น GET  แล้วกดปุ่ม Send

อธิบายโค้ด

var bodyParser = require('body-parser');

เรียกใช้ ไลบรารี่ body-parser เพื่ออำนวยความสะดวกในการแปลงรูปแบบ body ของ http เป็นรูปแบบต่างๆ

app.use(bodyParser.json());

กำหนดค่าให้ express ใช้งาน body แบบ json ได้

app.get('/get', function (req, res) {
  console.log('get data');
  res.send(data);
});

ใน function(req,res){} จะเป็นรูปแบบ return ค่าแบบ callback ซึ่งจะกล่าวถึงในตอนที่เกี่ยวข้องกับ callback ต่อไป จะสังเกตเห็นว่ามี ออบเจค req และ res ซึ่งหากย้อนกลับไปดูที่รูปที่ 1 ก็คือ request กับ response นั่นเอง

เมื่อมีการเรียกมาที่ /get ด้วย method GET ก็จะส่งค่า data กลับไปยังต้นทาง

app.post('/add', function (req, res) {
    console.log('add data');
    req.body.id = data.length +1;
    data.push(req.body);
    res.send(data);
});

เมื่อมีการเรียกมาที่ /add ด้วย method POST ก็จะเพิ่มข้อมูลเข้าไปยัง data และส่ง data กลับไปยังต้นทาง

app.put('/edit', function (req, res) {
  if(req.body.id)
    data[req.body.id-1] = req.body;
  console.log("edit data!");
  res.send(data);
});

เมื่อมีการเรียกมาที่ /edit ด้วย method PUT ก็จะแก้ไขข้อมูลที่ตำแหน่งของ อาร์เรย์ตำแหน่งที่ id -1 ใน data และส่ง data กลับไปยังต้นทาง

app.delete('/delete', function (req, res) {
  if(req.body.id)
    data.splice(req.body.id-1,1);
  console.log("delete data!");
  res.send(data);
});

เมื่อมีการเรียกมาที่ /delete ด้วย method DELETE ก็จะลบข้อมูลที่ตำแหน่งของ อาร์เรย์ตำแหน่งที่ id -1 ใน data และส่ง data กลับไปยังต้นทาง

ติดตามตอนที่ 6 เทคนิคการแยก Route ไว้หลายๆไฟล์