บทก่อนหน้าใช้ Angular สร้างส่วนติดต่อผู้ใช้ แต่แอปจริงต้องมีข้อมูลจาก server เช่น รายการสินค้า ผู้ใช้ คำสั่งซื้อ หรือผลการค้นหา บทนี้จึงอธิบายวิธีที่ front-end ติดต่อ back-end ผ่าน REST API โดยใช้ HTTP request/response และแลกเปลี่ยนข้อมูลด้วย JSON
คำสำคัญของบทเรียน
API เปรียบเหมือนสัญญาการสื่อสารระหว่าง front-end และ back-end โดย front-end ต้องรู้ว่า endpoint คืออะไร ต้องส่งข้อมูลแบบใด และจะได้รับ response แบบใดกลับมา หากสัญญานี้ชัดเจน ทีม front-end และ back-end สามารถพัฒนาคู่ขนานกันได้ง่ายขึ้น
%%{init: {'theme': 'base', 'themeVariables': {
'background': '#282828',
'primaryColor': '#3c3836',
'primaryTextColor': '#fbf1c7',
'primaryBorderColor': '#fabd2f',
'lineColor': '#83a598',
'secondaryColor': '#504945',
'tertiaryColor': '#665c54',
'fontFamily': 'Arial'
}}}%%
flowchart LR
A[Front-end
Angular/Web UI] --> B[HTTP Request
คำขอ]
B --> C[REST API
Web Service]
C --> D[Database
ฐานข้อมูล]
D --> C
C --> E[HTTP Response
ผลลัพธ์ JSON]
E --> A
| ฝั่งระบบ | หน้าที่ |
|---|---|
| Front-end | แสดง UI รับ input และเรียก API |
| REST API | รับ request ตรวจสอบข้อมูล และส่ง response |
| Back-end Logic | ประมวลผล business rules |
| Database | จัดเก็บและค้นคืนข้อมูล |
| API Document | อธิบาย endpoint, request และ response |
REST หรือ Representational State Transfer เป็นแนวทางออกแบบ API ที่มองข้อมูลเป็น Resource เช่น products, users, orders แล้วใช้ URL แทน resource และใช้ HTTP method ระบุการกระทำ
/products ไม่ใช่ /getProductsGET, POST, PUT, DELETE| รูปแบบ URL | ความหมาย | เหมาะสมหรือไม่ |
|---|---|---|
GET /products |
อ่านรายการสินค้า | เหมาะสม |
GET /products/10 |
อ่านสินค้ารหัส 10 | เหมาะสม |
POST /products |
เพิ่มสินค้าใหม่ | เหมาะสม |
GET /getAllProducts |
ใช้ verb ใน URL | ควรปรับ |
POST /deleteProduct |
ใช้ method ไม่ตรงงาน | ควรปรับ |
JSON หรือ JavaScript Object Notation เป็นรูปแบบข้อมูลที่อ่านง่ายและใช้ได้หลายภาษา เหมาะกับการส่งข้อมูลระหว่าง front-end และ back-end
{
"id": 1,
"name": "Keyboard",
"price": 850,
"category": "Device",
"inStock": true
}
{
"data": [
{
"id": 1,
"name": "Keyboard",
"price": 850
},
{
"id": 2,
"name": "Mouse",
"price": 420
}
],
"total": 2
}
| ชนิดข้อมูล JSON | ตัวอย่าง |
|---|---|
| String | "Keyboard" |
| Number | 850 |
| Boolean | true |
| Object | { "id": 1 } |
| Array | [1, 2, 3] |
| Null | null |
CRUD เป็นงานพื้นฐานของระบบข้อมูล ได้แก่ เพิ่ม อ่าน แก้ไข และลบ REST API จะจับคู่ CRUD กับ HTTP methods เพื่อให้ API อ่านง่ายและเป็นมาตรฐาน
%%{init: {'theme': 'base', 'themeVariables': {
'background': '#282828',
'primaryColor': '#3c3836',
'primaryTextColor': '#fbf1c7',
'primaryBorderColor': '#fabd2f',
'lineColor': '#b8bb26',
'secondaryColor': '#504945',
'tertiaryColor': '#665c54',
'fontFamily': 'Arial'
}}}%%
flowchart TD
A[CRUD
งานจัดการข้อมูล] --> B[Create
เพิ่มข้อมูล]
A --> C[Read
อ่านข้อมูล]
A --> D[Update
แก้ไขข้อมูล]
A --> E[Delete
ลบข้อมูล]
B --> F[POST]
C --> G[GET]
D --> H[PUT/PATCH]
E --> I[DELETE]
| งาน | HTTP Method | Endpoint | คำอธิบาย |
|---|---|---|---|
| Read list | GET |
/products |
อ่านรายการสินค้า |
| Read one | GET |
/products/1 |
อ่านสินค้ารายการเดียว |
| Create | POST |
/products |
เพิ่มสินค้าใหม่ |
| Replace | PUT |
/products/1 |
แก้ไขข้อมูลทั้งรายการ |
| Partial update | PATCH |
/products/1 |
แก้ไขบาง field |
| Delete | DELETE |
/products/1 |
ลบสินค้า |
Status Code ช่วยบอกผลลัพธ์ของ request ให้ front-end รู้ว่าควรทำอะไรต่อ เช่น แสดงข้อมูล แสดง error หรือให้ผู้ใช้ login ใหม่
| กลุ่ม | ความหมาย | ตัวอย่าง |
|---|---|---|
2xx |
สำเร็จ | 200 OK, 201 Created, 204 No Content |
3xx |
redirect | 301 Moved Permanently, 304 Not Modified |
4xx |
client error | 400 Bad Request, 401 Unauthorized, 404 Not Found |
5xx |
server error | 500 Internal Server Error, 503 Service Unavailable |
{
"error": {
"code": "PRODUCT_NAME_REQUIRED",
"message": "กรุณาระบุชื่อสินค้า",
"field": "name"
}
}
การออกแบบ endpoint ควรเริ่มจาก resource หลักของระบบ เช่น products, categories, orders แล้วกำหนด action ผ่าน HTTP method
GET /products
GET /products/{id}
POST /products
PUT /products/{id}
PATCH /products/{id}
DELETE /products/{id}
GET /products?keyword=keyboard&category=device
POST /products
Content-Type: application/json
{
"name": "Keyboard",
"price": 850,
"category": "Device"
}
HTTP/1.1 201 Created
Content-Type: application/json
{
"id": 1,
"name": "Keyboard",
"price": 850,
"category": "Device"
}
API ต้องเลือกตำแหน่งการส่งข้อมูลให้เหมาะสม เพื่อให้ endpoint อ่านง่ายและคาดเดาได้
| ส่วนของ Request | ตัวอย่าง | ใช้เมื่อ |
|---|---|---|
| Path Parameter | /products/10 |
ระบุ resource เฉพาะรายการ |
| Query Parameter | /products?keyword=mouse |
ค้นหา กรอง เรียงลำดับ หรือแบ่งหน้า |
| Request Body | { "name": "Keyboard" } |
ส่งข้อมูลสำหรับสร้างหรือแก้ไข |
| Header | Authorization: Bearer token |
ส่ง metadata เช่น token หรือ content type |
// Angular service เรียก API พร้อม query parameter
getProducts(keyword: string) {
return this.http.get('/api/products', {
params: { keyword }
});
}
Swagger/OpenAPI คือรูปแบบเอกสาร API ที่บอก endpoint, method, parameter, request body, response และ status code อย่างเป็นระบบ ทีม front-end สามารถดูเอกสารนี้เพื่อรู้วิธีเรียก API โดยไม่ต้องเดา
%%{init: {'theme': 'base', 'themeVariables': {
'background': '#282828',
'primaryColor': '#3c3836',
'primaryTextColor': '#fbf1c7',
'primaryBorderColor': '#fabd2f',
'lineColor': '#d3869b',
'secondaryColor': '#504945',
'tertiaryColor': '#665c54',
'fontFamily': 'Arial'
}}}%%
flowchart LR
A[API Design
ออกแบบ endpoint] --> B[OpenAPI Spec
เอกสารมาตรฐาน]
B --> C[Swagger UI
หน้าเอกสาร]
C --> D[Front-end Team
เรียกใช้งาน]
C --> E[Back-end Team
ตรวจสัญญา API]
paths:
/products:
get:
summary: Get product list
responses:
'200':
description: Product list
Postman เป็นเครื่องมือสำหรับส่ง request ไปยัง API และดู response เหมาะกับการทดสอบ endpoint ก่อนนำไปเชื่อมกับ front-end
GET หรือ POSThttp://localhost:3000/productsContent-Type: application/jsonPOST, PUT หรือ PATCH| สิ่งที่ต้องตรวจ | ตัวอย่างคำถาม |
|---|---|
| Method | ใช้ GET, POST, PUT, PATCH, DELETE ถูกหรือไม่ |
| URL | endpoint ถูกต้องหรือไม่ |
| Header | ระบุ Content-Type หรือ token หรือไม่ |
| Body | JSON ถูกต้องและ field ครบหรือไม่ |
| Status Code | response ตรงกับผลลัพธ์หรือไม่ |
| Response | ข้อมูลกลับมาในรูปแบบที่ front-end ใช้ต่อได้หรือไม่ |
เวลา response ของ API ส่งผลต่อประสบการณ์ผู้ใช้โดยตรง หาก API ช้า front-end ควรมี loading state และถ้าเกิด error ต้องมีข้อความแจ้งชัดเจน
ตัวอย่างนี้ต่อจากบท Angular โดยแยกการเรียก API ไว้ใน service และให้ component ใช้ service เพื่อโหลดข้อมูลสินค้า
// product-api.service.ts
import { HttpClient } from '@angular/common/http';
import { Injectable, inject } from '@angular/core';
export interface Product {
id: number;
name: string;
price: number;
}
@Injectable({
providedIn: 'root'
})
export class ProductApiService {
private http = inject(HttpClient);
getProducts() {
return this.http.get<Product[]>('/api/products');
}
}
// products.component.ts
import { Component, inject } from '@angular/core';
import { ProductApiService } from './product-api.service';
@Component({
selector: 'app-products',
templateUrl: './products.component.html'
})
export class ProductsComponent {
private productApi = inject(ProductApiService);
products$ = this.productApi.getProducts();
}
| รายการตรวจ | คำถามที่ต้องตอบ |
|---|---|
| Resource | ตั้งชื่อ endpoint เป็นคำนามและอ่านเข้าใจหรือไม่ |
| Method | จับคู่ CRUD กับ HTTP method ถูกต้องหรือไม่ |
| JSON | request/response เป็น JSON ที่ชัดเจนหรือไม่ |
| Status Code | ใช้ status code สอดคล้องกับผลลัพธ์หรือไม่ |
| Error | error response มี code/message/field หรือไม่ |
| Postman | ทดสอบ endpoint และบันทึก collection แล้วหรือไม่ |
| Swagger | มีเอกสาร API ให้ทีมอื่นเข้าใจหรือไม่ |
ออกแบบ REST API สำหรับระบบ Product Management โดยให้มี: