WEB · เสริม: Backend Backend

หัวข้อ 16 · 16 นาที · เสริม

Backend และ REST API

นึกภาพก่อน

ร้านอาหาร: หน้าร้าน คือสิ่งที่ลูกค้าเห็นและสัมผัส ครัว คือที่ทำอาหารและเก็บวัตถุดิบ ลูกค้าไม่เข้าครัว ทั้งสองฝั่งคุยกันผ่าน เมนู: รายการที่บอกว่าสั่งอะไรได้ และจะได้อะไรกลับมา

  • หน้าร้าน = frontend (HTML, CSS, JavaScript, React ใน browser)
  • ครัว = backend (โปรแกรมบน server และฐานข้อมูล)
  • เมนู = API

Frontend กับ Backend

FrontendBackend
ทำงานที่browser ของผู้ใช้server
หน้าที่แสดงผล รับ inputเก็บข้อมูล ตรวจสิทธิ์ ทำ business logic
ผู้ใช้เห็นโค้ดไหมเห็น (เปิด DevTools ได้)ไม่เห็น
เครื่องมือในวิชานี้HTML, JavaScript, React, Next.jsNode.js, Express.js

เพราะโค้ดฝั่ง frontend ถูกเปิดดูและแก้ได้ การตรวจสอบที่สำคัญต้องทำที่ backend เสมอ (เช่น สิทธิ์ ราคา รหัสผ่าน)

API

API (Application Programming Interface) คือ ข้อตกลง ว่า client จะขออะไรจาก server ได้ ด้วยรูปแบบใด และจะได้อะไรกลับมา web API ใช้ HTTP เป็นช่องทาง และมักใช้ JSON เป็นรูปแบบข้อมูล

แต่ละจุดที่เรียกได้เรียกว่า endpoint = method + path เช่น GET /users

REST

REST เป็นแนวทางออกแบบ API ที่ใช้ความสามารถของ HTTP ตรง ๆ:

  1. ทุกอย่างเป็น resource ที่ระบุด้วย URL (ใช้คำนาม พหูพจน์): /users, /users/42
  2. HTTP method บอกว่าจะทำอะไรกับ resource
  3. Status code บอกผล
  4. Stateless: ทุก request มีข้อมูลครบในตัวเอง server ไม่จำ request ก่อนหน้า (ตรงกับสไลด์ HTTP)

Method กับ CRUD

การกระทำ (CRUD)Methodตัวอย่างbody ของ requeststatus เมื่อสำเร็จ
CreatePOSTPOST /usersข้อมูลของ user ใหม่201 Created
Read (ทั้งหมด)GETGET /users–200 OK
Read (ตัวเดียว)GETGET /users/42–200 OK
Update (ทั้งตัว)PUTPUT /users/42ข้อมูลใหม่ทั้งหมด200 OK
Update (บางส่วน)PATCHPATCH /users/42เฉพาะ field ที่แก้200 OK
DeleteDELETEDELETE /users/42–204 No Content

ออกแบบ URL ด้วย คำนาม ไม่ใช่คำกริยา: DELETE /users/42 ไม่ใช่ GET /deleteUser?id=42 — คำกริยาอยู่ที่ method แล้ว

คุณสมบัติของ method

MethodSafe (ไม่แก้ข้อมูล)Idempotent (ทำซ้ำได้ผลเดิม)
GET✓✓
PUT✗✓
DELETE✗✓
POST✗✗ (ส่งสองครั้งได้สองรายการ)
PATCH✗ไม่รับประกัน

ส่งข้อมูลไป server ได้ทางใด

ทางตัวอย่างใช้กับ
Path parameter/users/42ระบุ resource ตัวใดตัวหนึ่ง
Query string/users?role=admin&page=2กรอง เรียง แบ่งหน้า
Body{ "name": "Ann" }ข้อมูลที่จะสร้างหรือแก้ (POST, PUT, PATCH)
HeaderAuthorization: Bearer <token>ข้อมูลกำกับ เช่น การยืนยันตัวตน

request ที่มี body แบบ JSON ต้องมี header Content-Type: application/json

Status code ที่ API ใช้บ่อย

ตรงกับตารางในสไลด์ HTTP:

สถานการณ์Status
ดึงข้อมูลสำเร็จ200 OK
สร้างสำเร็จ201 Created
ลบสำเร็จ ไม่มีอะไรส่งกลับ204 No Content
ข้อมูลที่ส่งมาไม่ถูกต้อง400 Bad Request
ยังไม่ login / token ไม่ถูก401 Unauthorized
login แล้วแต่ไม่มีสิทธิ์403 Forbidden
ไม่มี resource นี้404 Not Found
ข้อมูลซ้ำ เช่น email ถูกใช้แล้ว409 Conflict
server ผิดพลาดเอง500 Internal Server Error

เรียก API จาก frontend

js
// GET
const res = await fetch('http://localhost:3000/users');
const users = await res.json();

// POST
const res = await fetch('http://localhost:3000/users', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name: 'Ann', email: 'ann@example.com' }),
});

if (!res.ok) {                        // ok เป็น true เมื่อ status อยู่ในช่วง 200–299
  console.log('failed', res.status);
}
  • body ต้องเป็น string จึงต้อง JSON.stringify
  • res.json() แปลง body ที่เป็น JSON กลับเป็น object (ทำ JSON.parse ให้)
  • fetch ไม่ throw เมื่อได้ 404 หรือ 500 ต้องตรวจ res.ok หรือ res.status เอง

ตัวอย่างไล่ทีละขั้น

โจทย์: ออกแบบ API สำหรับ "สินค้า" (products) ให้ครบ CRUD และบอก request กับ response ของการสร้างสินค้า

ต้องการEndpoint
ดูสินค้าทั้งหมดGET /products
ดูเฉพาะหมวด shoesGET /products?category=shoes
ดูสินค้า id 7GET /products/7
เพิ่มสินค้าPOST /products
แก้ราคาของ id 7PATCH /products/7
ลบ id 7DELETE /products/7

การสร้างสินค้า:

http
POST /products HTTP/1.1
Host: localhost:3000
Content-Type: application/json

{"name":"Sneaker","price":1990}
http
HTTP/1.1 201 Created
Content-Type: application/json

{"id":8,"name":"Sneaker","price":1990}
  1. method POST + path /products (ไม่มี id เพราะ server เป็นผู้กำหนด)
  2. Content-Type: application/json บอกว่า body เป็น JSON
  3. server ตอบ 201 (ไม่ใช่ 200) เพราะมี resource ใหม่เกิดขึ้น และส่งตัวที่สร้างพร้อม id กลับมา
  4. ถ้าไม่ส่ง name → server ควรตอบ 400 · ถ้าชื่อซ้ำกับที่มีอยู่ → 409

จุดที่มักพลาด

1. ใช้ GET ทำทุกอย่าง

GET ต้องไม่แก้ข้อมูล การสร้าง แก้ ลบ ใช้ POST, PUT/PATCH, DELETE

2. ใส่คำกริยาใน URL

/getUsers, /createUser ไม่ใช่ REST ใช้ /users กับ method

3. ตอบ 200 ทุกกรณี แล้วใส่ error ใน body

client ควรรู้ผลจาก status code

4. สลับ 401 กับ 403

401 = ยังไม่รู้ว่าเป็นใคร · 403 = รู้ แต่ไม่อนุญาต

5. สลับ PUT กับ PATCH

PUT แทนทั้งตัว · PATCH แก้บางส่วน

6. ลืม Content-Type ตอนส่ง JSON

server อ่าน body ไม่ออก

7. ตรวจข้อมูลเฉพาะที่ frontend

ผู้ใช้ข้าม frontend แล้วเรียก API ตรง ๆ ได้ ต้องตรวจที่ backend ด้วย

ที่มา: เนื้อหาเสริม ไม่มีเอกสารใน docs/WEB (ต่อยอดจาก HTTP for Developer.pdf หน้า 21–28)