API Fundamentals, Architectures & Core Components
11.1 พื้นฐานและรูปแบบของ API (API Fundamentals & Paradigms)
รากฐานของวิศวกรรม API ระดับองค์กร
🖼️ Technical Architecture Diagram: API Paradigms
- Client (Web/Mobile) initiates a request to the API Gateway.
- API Gateway routes the request to appropriate services (REST, GraphQL, gRPC).
- GraphQL handles complex data aggregation across multiple microservices.
- gRPC facilitates ultra-low latency communication between internal microservices.
🟢 Basic Level (ปูพื้นฐาน)
API คือพนักงานเสิร์ฟที่รับออเดอร์ (Request) จากลูกค้า ไปบอกพ่อครัว (Server) และนำอาหาร (Response) มาเสิร์ฟ
🟡 Intermediate Level (โค้ด/คอนฟิกจริง)
การตั้งค่า Route, Controller, และ Payload Validation ใน Node.js หรือ FastAPI ด้วย Schema ที่ชัดเจน
🔴 Professional Level (Under-the-hood & FinOps)
การทำ TCP Connection Pooling, การจูน HTTP Keep-Alive, และลด Egress Cost ด้วย Payload Compression (Brotli)
🏢 Real-World Enterprise Scenario
ระบบแอปธนาคารใช้ GraphQL เพื่อดึงยอดเงินและประวัติรวมกันใน 1 Request ลด Latency ในเครือข่าย 5G/4G
1. ประเภทของ API (Public, Private, Partner, Composite)
ทฤษฎีและกลไกการทำงาน
API ถูกแบ่งประเภทตามขอบเขตการเข้าถึงและการประกอบกัน:
- Private (Internal): ใช้เฉพาะภายในองค์กร มักใช้สำหรับการสื่อสารระหว่าง microservices
- Partner: แชร์ให้กับพาร์ทเนอร์ทางธุรกิจที่เจาะจง ต้องมีกระบวนการ Onboarding ที่เข้มงวด
- Public (Open): เปิดให้โปรแกรมเมอร์ทุกคนใช้งานได้ ต้องมีระบบ Security และ Rate limiting ที่แข็งแกร่ง
- Composite: การรวม API หลายๆ ตัวเข้าด้วยกันเป็น Endpoint เดียว เพื่อลดจำนวนครั้งที่ Client ต้องยิง Request
ตัวอย่างโค้ดหรือการตั้งค่า
// ตัวอย่าง Composite API Controller (Node.js/Express)
app.get('/api/composite/user-dashboard', async (req, res) => {
try {
const userId = req.user.id;
// ดึงข้อมูลจากหลาย microservices พร้อมๆ กัน (Concurrency)
const [profile, orders, recommendations] = await Promise.all([
fetchInternalAPI(`/users/${userId}`),
fetchInternalAPI(`/orders?userId=${userId}`),
fetchInternalAPI(`/recommendations/${userId}`)
]);
res.json({ profile, orders, recommendations });
} catch (err) {
res.status(500).json({ error: "Failed to assemble dashboard" });
}
});
Use Case ในชีวิตจริง
แพลตฟอร์ม E-commerce ใช้ Private API เพื่อให้ระบบ Inventory คุยกับระบบ Billing. มี Partner API ให้บริษัทขนส่ง (เช่น Kerry) อัปเดตสถานะพัสดุ. มี Public API ให้นักพัฒนาอิสระทำ Extension ติดตามราคา. และสุดท้าย Mobile App ใช้ Composite API เพื่อโหลดข้อมูลหน้าแรกทั้งหมดในการยิง Request เพียงครั้งเดียวแทนที่จะต้องยิง 5 ครั้ง
ข้อควรระวังและวิธีแก้
- ข้อควรระวัง: การเผลอปล่อย Private API ให้เข้าถึงได้จากอินเทอร์เน็ตสาธารณะ (Public internet)
- วิธีแก้: ตั้งค่า API Gateway routing ให้รัดกุม, แยก Network ด้วย VPC (Virtual Private Cloud), และบังคับใช้ Zero-trust authentication แม้จะเป็นการคุยกันเองภายใน (เช่น ใช้ mTLS)
2. REST vs SOAP vs GraphQL vs gRPC
ทฤษฎีและกลไกการทำงาน
- REST: อิงตาม Resource ใช้มาตรฐาน HTTP verbs (GET, POST) เรียบง่ายและเป็นที่นิยมสูงสุด
- SOAP: อิงตาม Protocol ใช้โครงสร้าง XML และ WSDL ที่เข้มงวด overhead สูงแต่มีมาตรฐาน Security/Transaction ในตัว (WS-Security)
- GraphQL: อิงตาม Query มี Endpoint เดียว Client สามารถระบุโครงสร้างข้อมูลที่ต้องการได้เป๊ะๆ แก้ปัญหา Over-fetching
- gRPC: อิงตาม RPC ใช้ Protocol Buffers (Binary) วิ่งบน HTTP/2 เร็วมาก มี Type ชัดเจน เหมาะสุดสำหรับการคุยกันเองของ Microservices
ตัวอย่างโค้ดหรือการตั้งค่า
// ไฟล์ gRPC Protobuf (user.proto)
syntax = "proto3";
service UserService {
rpc GetUser (UserRequest) returns (UserResponse) {}
}
message UserRequest {
string user_id = 1;
}
message UserResponse {
string user_id = 1;
string name = 2;
string email = 3;
}
Use Case ในชีวิตจริง
แอป Streaming ระดับโลก (เช่น Netflix) ใช้ gRPC สำหรับการสื่อสารความเร็วสูงระหว่างบริการหลังบ้าน (เช่น Auth service คุยกับ Profile service). ใช้ GraphQL สำหรับฝั่ง Frontend/Mobile เพื่อให้อุปกรณ์ต่างรุ่นดึงเฉพาะข้อมูลที่จะแสดงผล. และอาจยังต้องรักษา legacy SOAP API ไว้สำหรับการเชื่อมต่อกับระบบธนาคารรุ่นเก่าเพื่อตัดบัตรเครดิต
ข้อควรระวังและวิธีแก้
- ข้อควรระวัง: ปัญหา Over-fetching (ดึงข้อมูลมาเกินจำเป็น) ใน REST หรือการเขียน GraphQL Resolver ที่ซับซ้อนจนเกิดปัญหา N+1 Query ที่ฐานข้อมูล
- วิธีแก้: ใช้ GraphQL DataLoader เพื่อทำ Batch และ Cache query. สำหรับ REST ให้รองรับการทำ Partial response (เช่น `?fields=id,name`)
3. องค์ประกอบหลัก (Endpoints, Verbs, Headers, Body, Status Codes)
ทฤษฎีและกลไกการทำงาน
การออกแบบ REST API ที่ดีต้องพึ่งพาคุณสมบัติเชิงความหมาย (Semantic) ของ HTTP:
- Endpoints: คำนาม (Noun) ที่เป็นตัวแทนของข้อมูล (เช่น `/users/123/orders`)
- Verbs: การกระทำ (GET อ่าน, POST สร้าง, PUT/PATCH อัปเดต, DELETE ลบ)
- Headers: ข้อมูล Meta เช่น `Authorization`, `Content-Type`, `Accept`
- Body: ข้อมูล Payload หลัก (มักจะเป็น JSON)
- Status Codes: รหัสตอบกลับมาตรฐาน (200 OK, 201 Created, 400 Bad Request, 401 Unauthorized, 404 Not Found, 500 Internal Error)
ตัวอย่างโค้ดหรือการตั้งค่า
POST /api/v1/orders HTTP/1.1
Host: api.pipecraft.com
Authorization: Bearer eyJhbGci...
Content-Type: application/json
Idempotency-Key: req-5a3d-4c8d
{
"productId": "prod_991",
"quantity": 2
}
---
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/orders/ord_552
{
"orderId": "ord_552",
"status": "processing"
}
Use Case ในชีวิตจริง
เมื่อชำระเงินผ่านระบบ Stripe API, ระบบจะให้ POST ไปที่ `/v1/charges` โดยส่ง `Idempotency-Key` ไปใน Header ด้วย เพื่อที่ว่าถ้าเน็ตหลุดแล้วแอพเรายิงซ้ำ (Retry) Stripe จะรู้และไม่ตัดเงินลูกค้าซ้ำซ้อน. มันจะตอบกลับเป็น `201 Created` เมื่อสำเร็จ หรือ `402 Payment Required` ถ้าบัตรถูกปฏิเสธ
ข้อควรระวังและวิธีแก้
- ข้อควรระวัง: การตอบกลับด้วย `200 OK` เสมอแม้จะเกิด Error (โดยเอา Error ไปซ่อนไว้ใน JSON Body) การทำแบบนี้จะทำให้ระบบ Caching และเครื่องมือ Monitoring ต่างๆ พัง
- วิธีแก้: แมป Application Error ให้ตรงกับความหมายของ HTTP Status Codes (เช่น กลุ่ม 400 สำหรับความผิดฝั่ง Client, 500 ฝั่ง Server)
4. ความปลอดภัยพื้นฐาน (API Key, OAuth 2.0 PKCE, Rate Limiting)
ทฤษฎีและกลไกการทำงาน
- API Keys: Token แบบง่ายๆ ที่ส่งแนบไปใน Header เหมาะสำหรับการคุยระหว่าง Server-to-Server แต่ไม่ปลอดภัยสำหรับฝั่ง Mobile/Web
- OAuth 2.0 Auth Code with PKCE: มาตรฐานยุคใหม่สำหรับการมอบสิทธิ์แบบปลอดภัยในฝั่ง Public clients (SPA, Mobile apps) ใช้การเข้ารหัสสุ่มแบบไดนามิกแทนที่การฝัง Client Secret ไว้ในโค้ด
- Rate Limiting: การจำกัดจำนวนครั้งการเรียก API (เช่น 100 req/min) ต่อ IP หรือ User ID เพื่อป้องกันการโจมตี DDoS และการใช้งานผิดประเภท โดยใช้อัลกอริทึมอย่าง Token Bucket
ตัวอย่างโค้ดหรือการตั้งค่า
# การตั้งค่า Rate Limiting ใน API Gateway (Kong/Envoy)
rate_limiting:
policies:
- name: "standard_tier"
limit: 1000
window: 3600 # 1 hour
identifier: "http.request.headers.x-api-key"
response_headers:
- X-RateLimit-Limit
- X-RateLimit-Remaining
- X-RateLimit-Reset
Use Case ในชีวิตจริง
GitHub API มีการทำ Rate limiting อิงตามสถานะการล็อกอิน หากไม่ได้ล็อกอินจะยิงได้แค่ 60 ครั้งต่อชั่วโมง แต่ถ้าใช้ OAuth Token จะยิงได้ 5,000 ครั้งต่อชั่วโมง. ใน Response Header จะบอก Client ชัดเจนว่าสามารถยิงซ้ำได้อีกทีเมื่อไหร่ ช่วยป้องกันเซิร์ฟเวอร์ล่มและยังให้ประสบการณ์นักพัฒนา (DX) ที่ดี
ข้อควรระวังและวิธีแก้
- ข้อควรระวัง: การฝัง API Key แบบตายตัว (Hardcoding) ไว้ในโค้ด Frontend (React/iOS) ซึ่งสามารถถูกเจาะดูได้ง่ายด้วยการ Reverse engineer
- วิธีแก้: ห้ามใช้ Static API keys บน Public clients เด็ดขาด ให้ใช้ OAuth 2.0 + PKCE เพื่อขอ JWT ที่มีอายุสั้นแทน หรือใช้สถาปัตยกรรม BFF (Backend For Frontend) ซ่อน Key ไว้ฝั่งเซิร์ฟเวอร์
🛠️ Weekend Sandbox Challenge
สร้าง Multi-paradigm Gateway Service ของคุณเอง
- สร้าง REST API (Node.js/Python) ง่ายๆ สำหรับจัดการ `Products`
- สร้าง GraphQL endpoint ที่มัดรวมข้อมูล `Products` และ `Reviews` (ข้อมูลจำลอง) เข้าด้วยกัน
- เขียน Middleware ดัก API Key ถ้าผิดให้ตอบกลับเป็น `401 Unauthorized`
- เพิ่ม Rate Limiter พื้นฐาน (ใช้ Redis ก็ได้) ถ้าเกิน 5 ครั้ง/นาที ให้ตอบบล็อคด้วย `429 Too Many Requests`
เป้าหมาย: เพื่อให้เข้าใจความแตกต่างของแต่ละ Paradigm และเรียนรู้วิธีการทำงานของ Security Layer ในมุมมองของ Client อย่างแท้จริง
💼 Senior Technical Interview Q&A
Q: ในสถานการณ์ไหนที่คุณจะเลือกใช้ gRPC แทนที่จะเป็น REST?
A: ผมจะเลือกใช้ gRPC สำหรับการสื่อสารภายในระหว่าง Microservice ด้วยกันเองในกรณีที่ต้องการประสิทธิภาพสูง, Latency ต่ำ, และต้องการ Data Contract ที่เข้มงวด เพราะ gRPC ใช้ HTTP/2 และ Protocol Buffers ซึ่งแปลงข้อมูลไวกว่า JSON มากและกิน Bandwidth น้อยกว่า อย่างไรก็ตาม ผมจะยังคงใช้ REST (หรือ GraphQL) สำหรับ API ที่ให้ Client ภายนอกหรือ Web App ใช้งาน เนื่องจาก Web Browser รองรับ gRPC แบบ Native ได้จำกัด และโปรแกรมเมอร์ส่วนใหญ่คุ้นเคยกับ JSON/REST มากกว่า
Q: ทำไม OAuth 2.0 Implicit Flow ถึงถูกยกเลิก (Deprecated) และทำไมต้องเปลี่ยนมาใช้ PKCE แทน?
A: Implicit Flow คืนค่า Access Token มาตรงๆ ใน URL Fragment ซึ่งเสี่ยงต่อการถูกดักจับโดย Browser Extension ประสงค์ร้ายหรือการโจมตีแบบ Open Redirect. กระแส Auth Code แบบที่มี PKCE (Proof Key for Code Exchange) เข้ามาแก้ปัญหานี้ โดยให้ Client สร้างรหัสลับแบบสุ่ม (code_verifier) ทุกครั้งที่ขอล็อกอิน จากนั้น Server จะตรวจสอบความถูกต้องตอนที่เอา Code มาแลก Token เพื่อให้มั่นใจว่าแอปที่มาขอ Token เป็นคนเดียวกับที่เริ่มขอล็อกอินจริงๆ ไม่ใช่ผู้ที่ดักจับ Code ระหว่างทางไป